标准库 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' 函数时会出现此类错误消息。”已编辑: 话虽如此,这是我的解决方案中唯一包含有关tempnamwtempnam 的区域。

【问题讨论】:

“我在整个解决方案中只能找到这个函数的一个声明”——如果你可以在自己的代码中找到这些函数的 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 链接的主要内容,如果未能解决你的问题,请参考以下文章

C标准库——<stdio.h>

c/c++标准库中的文件操作总结

怎样用C语言编写程序判断字符串S1是不是包含字符串S2.(不使用库函数)

C 标准库参考手册

C 标准库参考手册

C标准库中的函数定义在哪里?