【问题标题】:Warning: Function return user-defined type which is incompatible with C警告:函数返回与 C 不兼容的用户定义类型
【发布时间】:2013-03-17 08:39:19
【问题描述】:

标题:

using namespace std;
extern "C" {
  string testFunc();
}

.cpp:

string testFunc()
{
  return string("test");
}

我在构建时收到此警告:

'testFunc' has C-linkage specified, but returns user-defined type 'string' (aka 'basic_string<char>') which is incompatible with C

我已经测试了我的函数,并且正确返回了“test”。

这个警告会引起任何问题吗?

我在 XCode 4.6 中使用 Apple LLVM 4.2、C99、所有默认设置。

【问题讨论】:

  • C 中没有 std::string 这样的东西。
  • 老实说,这似乎与编译器错误一样清楚。
  • “我已经测试了我的函数”——不是来自 C 代码。
  • LOL...这就是它没有崩溃的原因...@JimBalter

标签: c++ xcode llvm


【解决方案1】:

大概您将testFunc 的声明包装在extern "C" 中,因为您希望能够从C 程序中调用它。但是,当 C 程序调用此函数时,他们会得到一个 std::string,这与 C 完全不兼容。程序将无法管理它。

testFunc 不应该在 extern "C" 内部,或者它应该以 C 风格的方式返回字符串(可能是 const char*)。

对于与 C 兼容的类类型,它应该是一个标准布局类(在 C++11 术语中)。

标准布局类是这样的类:

  • 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
  • 没有虚函数 (10.3) 和虚基类 (10.1),
  • 对所有非静态数据成员具有相同的访问控制(第 11 条),
  • 没有非标准布局基类,
  • 要么在派生最多的类中没有非静态数据成员,并且最多有一个具有非静态数据成员的基类,要么没有具有非静态数据成员的基类,并且
  • 没有与第一个非静态数据成员相同类型的基类。

它的名称也不应该被弄乱,当类型位于命名空间或模板类型时会发生这种情况。

【讨论】:

  • @ReckHou 因为标准并没有说这是格式错误的。编译器只是警告您返回 std::string 与 C 链接不兼容。如果你尝试从 C 中调用这个函数,你肯定会遇到问题。
  • 这并不是它的名字没有被破坏;就是名称在 C 风格而不是 C++ 风格中被破坏,通常是通过前置下划线,但一些编译器(习惯于?)附加下划线。这里没有标准的修改,所以extern "C" 说做任何编译器实现者认为可行的事情。
猜你喜欢
  • 2012-10-08
  • 1970-01-01
  • 2022-01-14
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多