[这个问题有一个重复的问题,我可以找到,但这个答案是完全错误的,请参阅下面的 C 代码。]
据我了解,extern "C"C++ 中不会生成 C 代码。它只是一个链接指令。
我有一些这样的extern "C"故事要讲,但今天有一个让我困扰的故事。这是一个完全最新的VS2019,代码如下:
#include <stdint.h>
#include <stdlib.h>
#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 {
/* remove this const and MSVC makes no warning
leave it in and MSVC complains, a lot
GCC or clang could not care less
*/
const
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( void )
{
constexpr auto test_{ make_Test(42) };
return test_.x ;
}
Run Code Online (Sandbox Code Playgroud)
强制性 GODBOLT 链接:https://godbolt.org/z/ecdz1vqhq
关于该 const 的评论是我问题的要点。
MSVC extern "C" 很大程度上(完全?)没有文档记录。因此,我无法判断我是否违反了这个无证区域的一些规则。许多人声称这是某种“未完全实现”的 C11。
AFAIK 对于 C11(或任何其他 C)结构成员类型具有该 const 是非常好的。古老的海湾合作委员会当然不会在意。正如所见,GODBOLT 在线。
这只是VS2019的一个bug,还是我犯了一个bug?
更新
即使我将 的实现make_Test移至单独的 C 文件中,并将其显式编译为 C,此警告也将保持不变。
关于之前同一个问题的“答案” 。C 可以有 const 结构数据成员,当然,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;
}
Run Code Online (Sandbox Code Playgroud)
C++ 标准中不要求 C++ 实现与 C 实现成对出现。
C++ 标准中不要求所有在 C 和 C++ 中具有相似含义的构造在 C++ 实现与所有或部分 C 实现之间应该是二进制兼容的。甚至没有任何地方要求同一平台上的两个 C 实现应该兼容。
举一个非常简单的例子,一个人可以使用 实现(C 或 C++) ,sizeof(long) == 4并在同一平台(C 或 C++)上使用另一个实现sizeof(long) == 8,这绝对没有任何问题。
回到问题中的特定构造,任何特定的地方都没有要求,虽然struct在 C 和 C++ 中都是完全合法的,但在特定的 C 实现和特定的 C++ 实现中具有相同的布局或相同的参数传递约定。
extern "C"帮助程序员生成与 C 互操作的代码,但该标准不能保证任何特定的构造都能工作,因为 C++ 标准不管理 C 实现。
TL;DR 这不是不符合任何标准的情况,这是特定 C++ 实现和特定 C 实现之间不幸但完全合法的不兼容。由于它们都来自同一生产商,因此它们知道不兼容性,并且您会得到一个很好的警告。
| 归档时间: |
|
| 查看次数: |
631 次 |
| 最近记录: |