如何使用 typeof_unqual 避免编译器关于丢弃 const 限定符的警告

Pet*_*aut 5 c constants typeof c23

在下面的代码中,copyThing()编写了其返回值与其参数值具有相同类型的代码:

extern void *copyThingImpl(const void *x);

#define copyThing(x) ((typeof(x)) copyThingImpl(x))

void foo(void);

void foo(void)
{
    char *x = "foo";
    char *y;

    y = copyThing(x);
    (void) y;
}
Run Code Online (Sandbox Code Playgroud)

这使用了广泛可用的typeof运算符。这工作正常并且编译时没有警告(例如,gcc -Wall -O2 -c test.c)。

现在,如果我们改为x指针const,我们会遇到一些小问题:

extern void *copyThingImpl(const void *x);

#define copyThing(x) ((typeof(x)) copyThingImpl(x))

void foo(void);

void foo(void)
{
    const char *x = "foo";
    char *y;

    y = copyThing(x);
    (void) y;
}
Run Code Online (Sandbox Code Playgroud)

这会导致警告:

warning: assignment discards 'const' qualifier from pointer target type
Run Code Online (Sandbox Code Playgroud)

这是正确的,因为(typeof(x))(const char *),所以分配给 nonconst y将会删除const

我的理解是,typeof_unqualC23 中新增的运算符应该能够解决这种情况。所以我尝试

warning: assignment discards 'const' qualifier from pointer target type
Run Code Online (Sandbox Code Playgroud)

如果我使用适当的 C23 启用选项(例如,gcc -Wall -O2 -std=c2x -c test.c)进行编译,我仍然会从各种 gcc 和 clang 版本中收到相同的警告。

我正确使用这个吗?typeof_unqual如果这行不通,那还有什么意义呢?

Bar*_*mar 0

typeof_unqual仅删除顶级限定符。所以会转

const char * const
Run Code Online (Sandbox Code Playgroud)

const char *
Run Code Online (Sandbox Code Playgroud)

但在您的示例中,const适用于指向的类型,而不是变量本身,因此它不是顶级限定符。