【发布时间】:2019-08-09 14:14:31
【问题描述】:
[this question 有一个我可以找到的 SO 重复项,但该答案完全错误,请参阅下面的 C 代码。]
我了解extern "C" 不会在您的 C++ 中间生成 C 代码。它只是一个链接指令。
我有一些extern "C" 的故事要讲,但今天有一个让我感到困扰。这是一个完全最新的VS2019,代码如下:
#ifdef __cplusplus
extern "C" {
#endif
// NOTE: in here it is still C++ code,
// extern "C" is a linkage directive
typedef struct Test Test;
struct Test {
const /* remove this const and MSVC makes no warning */
uint32_t x;
} ;
/*
MSVC throws warning C4190: 'make_Test' has C-linkage specified,
but returns UDT 'Test' which is incompatible with C
: see declaration of 'Test'
*/
inline constexpr Test make_Test(uint32_t x)
{
return Test{ x };
}
#ifdef __cplusplus
}
#endif
int main(const int argc, const char * argv[])
{
constexpr auto test_{ make_Test(42) };
return 42 ;
}
关于那个 const 的评论是我问题的要点。
MSVC extern "C" 在很大程度上(完全?)没有记录。因此,我无法判断我是否在这个无证区域违反了某些规则?许多人声称这是某种“未完全实施”的 C11?
AFAIK 具有 C11(或任何其他 C)结构成员类型的 const 是完全可以的。好老的 G++ 也不在乎:https://wandbox.org/permlink/7XfH2i21Yfnb7BDw 当然。
这只是VS2019的一个bug,还是我自己弄的一个bug?
更新
即使我将 make_Test 的实现移动到单独的 C 文件中,并将其显式编译为 C,此警告仍将保持不变。
关于之前the same question 的“答案”。 C 可以有 const struct 数据成员,当然,C 结构可以在创建时进行列表初始化。请看下面的代码:
// gcc prog.c -Wall -Wextra -std=gnu11 "-Wno-unused-parameter" "-Wno-unused-variable"
#include <stdlib.h>
typedef struct Test { const long x; } Test;
static struct Test make_Test(long x)
{
struct Test test_ = { x } ;
return test_;
}
int main(const int argc, const char * argv[])
{
struct Test test_ = make_Test(42) ;
return 42;
}
【问题讨论】:
-
我重新打开了它。 The other question 这是重复的,只有错误的答案。
-
inline在标头和constexpr中的定义我认为不符合 C 标准。构造函数调用Test{ x }两者都不是(应该是return (Test) { x = x };) -
好的,看看上面的 C 代码段,什么是合法的 C。其余的这是一个警告,但仅由最新的 MSVC 生成。
-
我很确定您应该研究一下适合 C 链接的 C++ 标准
-
对于 C,ISO C一直支持
const成员
标签: c++ c visual-c++