为清晰起见,是否应使用返回类型的无用类型限定符?

mpo*_*llo 11 c static-analysis coding-style const

当我们在头文件中有原型时,我们的静态分析工具会抱怨"返回类型上的无用类型限定符",例如:

const int foo();
Run Code Online (Sandbox Code Playgroud)

我们这样定义它是因为函数返回一个永远不会改变的常量,认为API似乎更清晰const.

我觉得这类似于为了清楚明确地将全局变量初始化为零,即使C标准已经声明如果未明确初始化所有全局变量将被初始化为零.在一天结束时,它真的没关系.(但静态分析工具并没有抱怨.)

我的问题是,有什么理由可以导致问题吗?我们是否应该忽略该工具产生的错误,或者我们是否应该以不太清晰和一致的API的可能成本来安抚该工具?(它返回const char*该工具没有问题的其他常量.)

Car*_*rum 25

通常,您的代码最好尽可能准确地描述正在发生的事情.你得到这个警告,因为constin const int foo();基本上没有意义.如果您不知道const关键字的含义,那么API似乎更清晰.不要超载这样的含义; static虽然很糟糕,但没有理由增加混淆的可能性.

const char *意味着不同的东西const int,这就是为什么你的工具不会抱怨它.前者是一个指向常量字符串的指针,这意味着调用返回该类型的函数的任何代码都不应该尝试修改字符串的内容(例如,它可能在ROM中).在后一种情况下,系统无法强制您不对返回的内容进行更改int,因此限定符无意义.与返回类型更接近的是:

const int foo();
char * const foo2();
Run Code Online (Sandbox Code Playgroud)

这将导致静态分析发出警告 - 将一个const限定符添加到返回值是一个毫无意义的操作.只有你有一个引用参数(或返回类型)才有意义,就像你的const char *例子一样.

事实上,我刚刚做了一个小测试程序,GCC甚至明确警告过这个问题:

test.c:6: warning: type qualifiers ignored on function return type
Run Code Online (Sandbox Code Playgroud)

因此,不仅仅是您的静态分析程序在抱怨.

  • 除其他外,`const`通常不意味着"这永远不会改变".`const`通常意味着"你(API客户端)不能改变这个".当你处理指向const的指针时,区别是显而易见的. (7认同)
  • 同意.我对const返回类型的即时反应是假设return是一个不应该更改的共享缓冲区的引用/指针.我的心理模型是const适用于容器(例如变量),而不是内容.例如,在"const char*"中,const适用于指向字符串,而如果你有"const int i = 5;",你仍然可以在表达式中写"i + 1" - 你可以使用只要您不尝试更改变量,就可以使用值.使用简单的int返回,您实际上没有容器 - 只有一个值. (3认同)

Mar*_*som 5

您可以使用其他方法来说明您的意图,而不会使工具感到不满意。

#define CONST_RETURN

CONST_RETURN int foo();
Run Code Online (Sandbox Code Playgroud)

您没有问题,const char *因为这是声明一个指向常量字符的指针,而不是一个常量指针。

  • 宏是原始的吗?是。宏很丑吗?经常。宏很危险吗?有时。宏不好吗?宏是一种工具,工具可能会被不好地使用,但是我不会一概而论。 (6认同)
  • 但是,鉴于没有编译器检查该CONST_RETURN声明,因此添加注释是否更好?这样,至少看起来不像编译器必须检查的那样。 (3认同)