标准库 stdio.h 重载函数的第二个 C 链接
Posted
技术标签:
【中文标题】标准库 stdio.h 重载函数的第二个 C 链接【英文标题】:Second C Linkage of Overloaded Function for a Standard Library stdio.h 【发布时间】:2015-07-21 17:41:29 【问题描述】:在我的研究中,我读到 C 不支持重载。但是,此应用程序使用的是 C++,而不是 C。我也 无法修改 stdio.h。当我尝试将在 Visual Studio 2003 中编写的应用程序/项目移动到 Visual Studio 2010 时,会产生该错误。
我收到错误:
错误 C2733:不允许重载函数 '_tempnam_dbg' 的第二个 C 链接 c:...\stdio.h
和
错误 C2733:不允许重载函数 '_wtempnam_dbg' 的第二个 C 链接 c:...\include\stdio.h
导致相应错误的代码:
_Check_return_ _CRTIMP char * __cdecl _tempnam(_In_opt_z_ const char * _DirName, _In_opt_z_ const char * _FilePrefix);
...
_Check_return_ _CRTIMP wchar_t * __cdecl _wtempnam(_In_opt_z_ const wchar_t * _Directory, _In_opt_z_ const wchar_t * _FilePrefix);
我从this SO solution 读到“当使用一组不同的参数声明 extern 'C' 函数时会出现此类错误消息。”。已编辑:
话虽如此,这是我的解决方案中唯一包含有关tempnam
和wtempnam
的区域。
【问题讨论】:
“我在整个解决方案中只能找到这个函数的一个声明”——如果你可以在自己的代码中找到这些函数的 any 声明,那么它可能是一个错误。您应该完全依赖标准头文件来声明标准库中的函数。 您是否要编译.cpp
文件以外的文件?从我在网上可以找到的内容来看,您认为这是 C 错误而不是 C++ 似乎是正确的。此外,您不应该在没有充分理由的情况下重新定义标准库中的函数。这肯定会导致问题。
请见谅,之前我说“我只能找到这个函数的一个声明”的时候我是不正确的。显示的代码是我能找到的唯一相关代码,取自 stdio.h
编译器认为命名的两个函数被重载,这意味着它必须看到每个名称的多个声明。如果涉及的唯一声明在标准标头中,则标准条件包含指令应该防止这种情况发生。不过,VS2010 的 C 库可能有问题。作为一个疯狂的猜测,如果在一个地方包含stdio.h
,但在另一个地方包含cstdio
,则可能会出现这样的错误。不管这是否解释,在任何地方切换到cstdio
都不是一个坏主意。
【参考方案1】:
由于您使用的是 C++ 而不是 C,因此您应该使用 #include <cstdio>
而不是 #include <stdio.h>
。同样适用于 stdlib、stdarg、string、math、errno、stdint 等。这些具有正确的声明,可以在 C++ 中正常工作。
【讨论】:
【参考方案2】:首先,stdio.h 是 C 而不是 C++ 的一部分,因此其中包含的任何内容都可能介于 extern "C"
之间,这意味着 C 符号不会被破坏,因此函数重载是不可能的。
在 C++ 中,函数重载使用名称修饰(基于名称和参数列表)来工作,因此如果您在两个地方声明了 _tempnam(const char*, const char*)
,它仍然无法工作,因为参数列表是相同的。
查找 C++ 名称修改。
https://en.wikipedia.org/wiki/Name_mangling
此外,tempnam 似乎是 Microsoft 独有的功能。 https://msdn.microsoft.com/en-us/library/hs3e7355.aspx
因为我只能在 C 标准库中找到 tmpnam。 http://en.cppreference.com/w/c/io/tmpnam
【讨论】:
以上是关于标准库 stdio.h 重载函数的第二个 C 链接的主要内容,如果未能解决你的问题,请参考以下文章