c++ - `char * const` 字段被 MSVC (VS2015) 视为 "incompatible with C"

标签 c++ visual-c++ struct extern

我有以下代码,在 VS2015 中编译时不会出现警告(启用所有警告):

// buffer.h

typedef struct {
    char * const start; // start of the buffer
    char * const end;   // one byte after the end of the buffer
    char * pos;         // current position
} Buffer;

static inline Buffer Buffer_create(char *buffer, int size) {
    Buffer b;

    char ** const startPtr = &((char *)b.start);
    char ** const endPtr = &((char *)b.end);

    *startPtr = buffer;
    *endPtr = buffer + size;
    b.pos = buffer;

    return b;
}

由于 .start.end 成员是 const,我正在进行强制转换以避免收到编译警告,并且代码确实如此编译时不会出现警告并且工作时不会出现问题。

但是,如果我想使用 gtest 对此进行测试,并且如果我想从 .cpp 文件引用此文件:

// some_file.cpp

extern "C" {
    #include "buffer.h"
}

我得到了C4190 warning来自 Visual Studio,描述为:

'Buffer_create' has C-linkage specified, but returns UDT 'Buffer' which is incompatible with C

但是 UDT 显然“与 C 兼容”,因为我可以在没有警告的情况下构建它,直到我尝试从 cpp 文件引用它。

如果我从 struct 定义中删除 const,警告就会消失。

所以,MSVC 似乎认为 char * const 不“与 C 兼容”。我是否在做非法的事情,或者这是一个编译器错误?

最佳答案

根据the documentation you linked对于警告 C4190,不支持从 C 和 C++ 调用按值返回 struct 的函数。

(在 C++ 标准中,语言混合的大部分细节都是以实现定义的形式给出的,在这种情况下,MSVC 通过记录不支持这一点来遵守)。

我也不建议在编译为 C 和 C++ 的 header 中使用 inline 函数,因为 inline 的语义在两种语言之间有所不同,因此这是自找麻烦。

如果您想在两种语言中使用 Buffer_create,则必须进行重大设计更改才能避免此问题。例如,通过指针输出参数“返回”结果,并取消 const 结构成员。

关于c++ - `char * const` 字段被 MSVC (VS2015) 视为 "incompatible with C",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45058667/

相关文章:

c++ - 特定模板参数的模板断点

c++ - 我遇到了可怕的 LNK2019 错误,不知道从这里开始。

struct - 如何转换作为结构体内部字段的枚举?

dictionary - 构造深层结构不起作用

c++ - vector::push_back 使用 std::move 进行内部重新分配

c++ - 返回与 C++ 中的类相同的类型

c++ - 了解 C++ 中运算符的范围

c++ - 非标准代码,还是 g++ 错误?

visual-c++ - 在 OpenGL 视口(viewport)中绘制标签的正确方法是什么?

c - typedef 结构错误。 '*' token 之前