SPDLOG의 'formatting of non-void pointers is disallowed'

발생한 에러 메시지: error C2338: static_assert failed: 'formatting of non-void pointers is disallowed'

 

에러 발생 코드

SPDLOG_INFO 함수 호출을 통해 glVersion을 출력하는 과정에서 에러가 발생하였다.

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    SPDLOG_ERROR("failed to initialize glad");
    glfwTerminate();
    return -1;
}
auto glVersion = glGetString(GL_VERSION);
SPDLOG_INFO("OpenGL context version: {}", glVersion); // 에러 발생

 

static_assert는 assert의 정적인 버전으로 컴파일 타임에 조건을 검사하여 컴파일 에러를 발생시킨다. static_assert가 발생한 곳을 살펴보자.

 

에러 발생 지점 확인

spdlog/fmt/bundled/base.h

value(const T&) {
// Formatting of arbitrary pointers is disallowed. If you want to format a
// pointer cast it to `void*` or `const void*`. In particular, this forbids
// formatting of `[const] volatile char*` printed as bool by iostreams.
static_assert(sizeof(T) == 0,
              "formatting of non-void pointers is disallowed");
}

해당 내용의 설명을 살펴보면, 임의의 포인터를 문자열로 포매팅하는 것은 허용되지 않는다. 정 포인터를 포매팅하고 싶으면 void* 또는 const void*로 형변환 하여 사용하라고 한다.

 

 


 

 

그러면 어떻게 해야 할까?

시도 방법 1. (void*)로 형변환

auto glVersion = glGetString(GL_VERSION);
SPDLOG_INFO("OpenGL context version: {}", (void*)glVersion);

// 출력: [2025-04-22 17:33:28.780] [info] [main.cpp:49] OpenGL context version: 0x1dd708300a8

주소값이 출력 된다.

 

 

시도 방법 2. glGetString() 반환형 확인 및 const char*로 형변환 (해결)

auto glVersion = glGetString(GL_VERSION);
SPDLOG_INFO("OpenGL context version: {}", reinterpret_cast<const char*>(glVersion));

// 출력: [2025-04-22 17:36:28.451] [info] [main.cpp:49] OpenGL context version: 3.3.0 NVIDIA 560.94

문자열이 출력된다.

 

 

크로노스 공식문서에서 glGetString의 Specification을 확인

const GLubyte *glGetString(GLenum name);

 

glad에 정의된 GLubyte 확인

// main.cpp
auto glVersion = glGetString(GL_VERSION);

// glad.h
#define glGetString glad_glGetString

// glad.c
PFNGLGETSTRINGPROC glad_glGetString = NULL;

// glad.h
typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC)(GLenum name);

// glad.h
typedef khronos_uint8_t GLubyte;

// khrplatform.h
typedef unsigned char          khronos_uint8_t;

unsigned char로 선언됨을 확인할 수 있다.

 

 

참고 자료