C++编译器错误:“在此作用域中未声明”

7
当我尝试编译一个C++ UDP客户端程序时,出现了一个奇怪的编译器错误。
以下是我的代码:g++ -o client Udp.cpp ClientMain.c -I. -lpthread
在文件ClientMain.c中包含了Udp.h,Udp.h中有一些问题:
1. 在析构函数“CUdpMsg::~CUdpMsg()”中,出现了错误:“error: 'free' was not declared in this scope”。
2. 在成员函数“void CUdpMsg::Add(in_addr_t, const void*, size_t)”中出现了错误:“error: 'malloc' was not declared in this scope”和“error: 'memcpy' was not declared in this scope”。
除此之外,在主函数“int main(int, char**)”中还有一些错误:
1. 在第28行出现了错误:“error: 'memcpy' was not declared in this scope”。
2. 在第29行出现了错误:“error: 'printf' was not declared in this scope”。
3. 在第30行和第35行出现了错误:“error: 'stdout' was not declared in this scope”。
4. 在第30行和第35行出现了错误:“error: 'fflush' was not declared in this scope”。
5. 在第34行出现了错误:“error: 'printf' was not declared in this scope”。
6. 在第37行出现了错误:“error: 'usleep' was not declared in this scope”。
我在cpp文件开头声明了以下内容。
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <cstdlib> 
#include <string>
#include <stdlib.h>
#include <cstring>

#include <errno.h>

'memcpy'等函数应该在string.h中声明...我已经将所有头文件包括string.h、string和cstring声明,但仍然出现编译器错误。有人知道这是为什么吗?谢谢。


2
你说你在你的“cpp”文件中有这些包含,但错误出现在ClientMain.c(注意是“.c”,不是“.cpp”)? - Georg Fritzsche
我认为你需要在UDP.h中包含一些那些文件。 - Djole
你是否为这些函数调用指定了std命名空间? - triclosan
@triclosan:如果你包含了C头文件(即.h文件),就不需要指定std::malloc - MSalters
@MSalters: 我同意。但是同时包含 <stdlib.h><cstdlib> 不是一个好的实践。 - triclosan
4个回答

8

你的Udp.h文件还需要包含所需的系统头文件。此外,由于你使用cstringcstdlib作为你的包含文件,因此你需要在所有 C 库函数前加上std::以限定命名空间,因为这些头文件不会自动导入到全局命名空间中。


或者它们必须在所有翻译单元中的“Udp.h”之前被包含(虽然这是不好的做法)。 - Björn Pollex

7

Mark B已经涵盖了您错误的所有确切原因。我只想补充一点,您应该尽量避免在单个cpp文件中混合使用两种C头文件的类型 (#include <cHEADER> vs #include <HEADER.h>)。

#include <cHEADER>类型会将所有包含的声明放入std::命名空间中。而#include <HEADER.h>文件中包含的声明则不会。当您需要使用std::malloc()但却需要使用::strncpy()时,维护代码会变得很麻烦。为每个文件选择一种方法,或者更好的是,为整个项目选择一种方法。

作为一个独立的问题,您遇到了一个头文件本身没有包含其所需内容的情况。这可能很烦人,因为错误可能会因为包含的顺序而出现或消失。

如果您创建了一个头文件/cpp对,请始终将匹配的头文件作为cpp文件中的第一个包含文件,这将保证头文件完整并可以独立存在。如果您创建了一个不需要实现的独立头文件,仍然可以创建一个空的.cpp文件来测试头文件的完整性,或者只运行头文件本身通过编译器。对于每个创建的头文件都这样做,将防止像您当前遇到的问题一样的头疼。


5
如果您有多个文件,则每个文件都需要适当的包含。也许它不在命名空间内?

0
一个更干净的解决方案可能是把 CUdpMsg::~CUdpMsg 的实现从 udp.h 移动到 udp.cpp,类似地,任何导致错误的函数也要这样处理。只有在真正简单(例如获取器)的情况下才在头文件中定义函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接