Clang-Tidy报“Suspicious comparison of 'sizeof(expr)' to a constant”警告的原因及消除逻辑咨询
嘿,这个问题我太熟了,来给你掰扯清楚~
首先得先搞懂Clang-Tidy为啥会弹这个警告:它本质上是在帮你揪出无意义的代码。你最初写的static_assert(sizeof (T) > 0);里,sizeof (T)是把T当成一个表达式来处理的(哪怕T是个类型,带括号的写法会被解析为表达式形式)。在C++里,任何合法表达式的sizeof结果都不可能是0——哪怕你用了[[no_unique_address]]修饰空类成员,空类本身的sizeof还是至少1,所以sizeof(expr) > 0这个比较永远为真,完全没必要写,Clang-Tidy自然会觉得这是可疑代码,给你发警告。
那为啥去掉括号写成static_assert(sizeof T > 0);警告就没了?这就得说sizeof的两种语法区别了:
- 一种是
sizeof(类型):专门用于类型的写法,比如sizeof(int); - 另一种是
sizeof 表达式:用于表达式,比如sizeof x(x是变量)。
当你写sizeof T的时候,这里的T是模板参数(类型),编译器会把它解析为类型的sizeof写法。这时候Clang-Tidy就明白你的意图了:你是想检查T是不是一个可以合法使用sizeof的类型——毕竟像void这种类型,是不能用sizeof T这种写法的(必须写sizeof(void),但C++里sizeof(void)本身就是非法的),所以这个static_assert其实是在拦截T为void或者其他不可sizeof的不完整类型的情况,是有实际意义的,自然就不会触发警告了。
再补充下你提到的[[no_unique_address]]:这个属性只是让空类成员不会占用额外的内存(类的大小可能被优化),但空类本身的sizeof还是至少1,所以不管有没有这个属性,非void的完整类型的sizeof都肯定大于0,你的断言核心还是在排除void这类非法类型,用sizeof T的写法刚好能让Clang-Tidyget到你的真实意图。
内容来源于stack exchange

