1、enum(枚举)没有枚举名
如果声明枚举类型时没有指定枚举名,其作用就和#define类似,比如以下代码:
enum { STATION_IDLE = 0, STATION_CONNECTING, STATION_WRONG_PASSWORD, STATION_NO_AP_FOUND, STATION_CONNECT_FAIL, STATION_GOT_IP };
这里声明了一个枚举类型确没有指定其枚举名,那么它就相当于用#define定义了六个名称和其对应的值,从0开始赋值每次加1,相当于:
#define STATION_IDLE = 0; #define STATION_CONNECTING = 1; #define STATION_WRONG_PASSWORD = 2; #define STATION_NO_AP_FOUND = 3; #define STATION_CONNECT_FAIL = 4; #define STATION_GOT_IP = 5;
只不过eunm类型表示的是一个确定的值,而这里#define了六个值,可见如果要表示同一个事件的不同反馈status,使用这种没有枚举名的枚举效果更好。
2、#pragma GCC diagnostic 编译器警告
头文件中有如下代码
#elif defined __GNUC__ #if (!defined(EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) #pragma GCC diagnostic push #endif // g++ warns about local variables shadowing member functions, which is too strict #pragma GCC diagnostic ignored "-Wshadow" #if __GNUC__ == 4 && __GNUC_MINOR__ < 8 // Until g++-4.7 there are warnings when comparing unsigned int vs 0, even in templated functions: #pragma GCC diagnostic ignored "-Wtype-limits" #endif #if __GNUC__>=6 #pragma GCC diagnostic ignored "-Wignored-attributes" #endif #endif
gcc编译器中
各个层次的gcc警告
从上到下覆盖
变量(代码)级:指定某个变量警告
int a __attribute__ ((unused));
指定该变量为"未使用的".即使这个变量没有被使用,编译时也会忽略则个警告输出.
文件级:在源代码文件中诊断(忽略/警告)
语法:
#pragma GCC diagnostic [error|warning|ignored] "-W<警告选项>"r"
诊断-忽略:(关闭警告) #pragma GCC diagnostic ignored "-Wunused" #pragma GCC diagnostic ignored "-Wunused-parameter" 诊断-警告:(开启警告) #pragma GCC diagnostic warning "-Wunused" #pragma GCC diagnostic warning "-Wunused-parameter" 诊断-错误:(开启警告-升级为错误) #pragma GCC diagnostic error "-Wunused" #pragma GCC diagnostic error "-Wunused-paramete
用法:
在文件开头处关闭警告,在文件结尾出再开启警告,这样可以忽略该文件中的指定警告.
项目级:命令行/编译参数指定
警告:
gcc main.c -Wall 忽略:
gcc mian.c -Wall -Wno-unused-parameter //开去all警告,但是忽略 -unused-parameter警告
选项格式: -W[no-]<警告选项>
如 : -Wno-unused-parameter # no- 表示诊断时忽略这个警告
3、函数指针typedef void (*T) (void *)的理解
void (*Func) (void *)定义了一个指向函数的指针,函数的返回值为 void 类型,后面的(void *)是函数的参数列表, void * 表示参数列表为void,加typedef表示函数指针的别名为Func,不加typedef也可以,但影响代码的阅读。
接下来我们就可以直接使用Func 来定义这种指针变量,
比如:Func fn1; //等价于void fn1 (void *);
使用:void func(void *); //声明函数
Func fn1; //定义变量
fn1=func; //赋值
(*fn1)(); //执行
typedef void (*intFunc)(int);//要定义的类型是void (*)(int),即参数一个int,什么也不返回的函数指针,定义的别名是intFunc。
在ros中NodeHandle类中subscribe()函数的几个重载版本都用了函数指针做形参,如下
template<class M, class T> Subscriber subscribe(const std::string& topic, uint32_t queue_size, void(T::*fp)(M), T* obj, const TransportHints& transport_hints = TransportHints()) { SubscribeOptions ops; ops.template initByFullCallbackType<M>(topic, queue_size, boost::bind(fp, obj, _1)); ops.transport_hints = transport_hints; return subscribe(ops); } ...................