零、前言
C++ 语言就是博大精深,各种语法问题,都值得深入探究一下,很多时候你觉得会用了、感觉明白了,真到使用的时候又会出现一些疑惑,这篇文章就来探究一下,C++中无名命名空间使用问题,问题的探究,是从下文章节一中的警告开始的。环境是在ubuntu16下使用vscode配置cmake命令编译调试的。
一、问题
在前段时间编码过程中,为了方便,我使用无名命名空间来定义函数,结果之前定义的函数中,有一个函数定义了没有使用,出现了形如下面的警告:
warning: ‘int ::{anonymous}::test2()’ defined but not used [-Wunused-function]
int test2()
^~~~~~~~~~~~
警告信息是gcc编译器给出的,意思也很明确:警告,匿名命名空间的函数test2没有被使用。
如果是定义在调用函数的后面,则会直接提示未声明的错误:
error: ‘test3’ was not declared in this scope
test3(); // 在这个地方调用test3()会直接报未定义错
^~~~~

这里只列出警告信息,后面会给出完成代码,带着这些疑问,我们继续下去。
二、无名空间
相信很多人都知道C++的命名空间,也经常使用命名空间,对于无名命名空间的使用也会有一些。这里还是简单提一下无名命名空间:又叫未命名的命名空间、匿名的命名空间,是指关键字namespace后紧跟花括号括起来的一系列声明语句,不需要对命名空间取名。
生命周期:无名命名空间中定义的变量拥有同静态变量一样的生命周期,在第一次使用前创建,直到程序结束才销毁。
作用域:无名命名空间中定义的成员的作用域与该命名空间所在的作用域相同,在某个源文件中定义无名命名空间,则该无名命名空间只在该源文件能访问。
使用方法:无名命名空间的成员可以在所定义的文件中直接使用,不需要使用命名空间的名字进行作用域限定。
注意事项:无名命名空间的成员名称不能与全局作用域的成员名称相同,会导致二义性。
三、gcc编译器警告和错误提示参数
上文中一提到警告信息是gcc编译器给出的,如果你对gcc相关的参数不熟悉的话,建议了解一下,强烈建议你看一下官方的,会有不少收获,当然都是英文,链接如下:
1、https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
英文看着费劲的话的,自己搜搜中文的吧。
四、问题解决
解决警告信息方法有两种,一种修改CMakeLists.txt文件,一种是使用系统提供的一些宏进行设置。
1、把CMakeLists.txt文件中的
set(CMAKE_CXX_FLAGS_DEBUG “$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb”)
命令中的-Wall去掉,即关闭警告,显然这样做不合理,毕竟我们在调试阶段是需要知道一些警告信息的,通过提前了解警告,避免后续程序出现问题。
2、使用系统提供的一些参数,去掉一些没有问题的警告,比如我定义的一个函数暂时没有使用,后续可能会用,不想让它每次都报警告,防止刷屏现象,那就可以对该函数做处理或者针对这一类警告做处理,不让它发出警告。
五、完整代码演示
注意看.cpp中的文字注释
1、工程结构如下:

2、具体工程文件
test.h如下:
#include <iostream>
using namespace std;
namespace ismile {
class Test
{
public:
Test(/* args */);
~Test();
int test();
private:
int test1();
};
}
test.cpp如下:
#include "test.h"
namespace ismile {
Test::Test(/* args */)
{
}
Test::~Test()
{
}
int Test::test1()
{
std::cout << "I'm test1 function." << std::endl;
return 0;
}
namespace {
__attribute__((unused)) int test2()
{
std::cout << "I'm test2 function." << std::endl;
return 0;
}
}
int Test::test()
{
test1();
test2(); // 如果不使用test2(),且不加__attribute__((unused))的话会报警告
//test3(); // 在这个地方调用test3()会直接报未定义错
return 0;
}
namespace {
int test3()
{
std::cout << "I'm test2 function." << std::endl;
return 0;
}
}
}
main.cpp如下:
#include <iostream>
#include <stdio.h>
#include "wall-test/test.h"
using namespace std;
int main(int argc, char* argv[]) {
ismile::Test test;
test.test();
return 0;
}
CMakeList.txt如下:
cmake_minimum_required (VERSION 3.0)
project(cpp-test)
set(targetname cpp-test)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_BUILD_TYPE "DEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
file(GLOB SRC_FILES "src/wall-test/*.cpp" "src/wall-test/*.h" "src/*.cpp")
source_group("Source Files" FILES ${SRC_FILES})
add_executable(${targetname} ${SRC_FILES})
target_link_libraries(${targetname}
)
原创不易,点赞关注吧。
本文探讨了C++中无名命名空间定义的函数未使用时,gcc编译器产生的"-Wunused-function"警告。通过分析无名命名空间的特性和gcc的警告选项,提出了两种解决方案:修改CMakeLists.txt或使用编译器参数抑制特定警告。作者还提供了完整代码示例来说明问题和解决办法。
698

被折叠的 条评论
为什么被折叠?



