[英]Are literal numbers treated as constants?
对于像PI这样的竞争对象,最好先#define它们或将它们声明为const,以便编译器可以进行优化,并且不易出错。 但是,我想知道语句中的立即数如何处理? 例如:
float x;
const int y = 60;
x = y / 3.0f;
在此示例中,将如何处理3.0f? 它会继承常量的优化吗?
将进行哪些优化取决于编译器。 在您的情况下,C和C ++编译器通常都将具有足够的信息来将源代码优化为相同的机器代码。 换句话说,它实际上并不太依赖于此代码中的字面量和常量 。
话虽如此,在C和C ++中, 字面量和常量的含义存在显着差异(并且您同时标记了问题C和C ++)。
60
和3.0f
是常数 ,但是y
不是常数 。 如果愿意,可以将y
称为const限定变量 ,但在C术语中它不是常数 ,从某种意义上说,单个y
在C中不是常数表达式 。 至于文字 ,在C语言中, 文字一词仅适用于字符串文字(以及C99中的复合文字 ),即,您的代码中根本没有文字。
60
和3.0.f
是文字 ,它们形成常量表达式 (分别为整数和浮点数)。 y
也是一个恒定 int
型,在一定意义上,单一y
是在C ++中的常量表达式 。 您可能会注意到差异的情况与优化无关,而与语言的定义方式无关。 例如,在文件范围数组类型声明中使用上述y
在C ++中是合法的,但在C中则不合法
typedef int int_array[y]; /* OK in C++, ERROR in C */
由于使用#define
要求预处理器进行文本替换,因此您的代码与以下代码相同:
#define VAL 3.0f
float x;
const int y = 60;
x = y / VAL;
直接const值的优化方式显然取决于编译器。 但是,如果您观看汇编代码(例如,由gcc生成的汇编代码),则会注意到编译器直接在浮点标准中编写了编码值3.0的二进制序列。
在某些体系结构上,可以直接使用的字符串文字的大小受到限制。 当字符串文字的大小太大时,编译器将需要将常量存储在只读数据存储器中的某个位置,然后在需要时从内存中加载值。
如果将值存储在常量变量中,则编译器很有可能仅存储常量的一个值并适当使用。 但是,如果使用##定义常量,则只会使预处理程序将文字值放入代码中,因此,编译器有可能无法意识到您正在使用相同的值并多次存储该常量。 正是由于这个原因,const变量比#defines更好。
答案取决于您使用的是C还是C ++,因此您需要选择一个并停止假装它们是同一件事。 在C中, const
关键字未声明常量 ; 它声明了一个变量,尝试对其进行修改的变量将调用未定义的行为。 在C语言中,永远不要声明const int y;
除非它是静态的/全局的,并且打算将内部信息从一个模块传递到另一个模块,而您不想在另一个模块的编译时将其固定(例如, const int my_library_version = 0x1001;
在共享库中可能很有用,尽管函数调用返回的值会更干净)。
至于优化,据我所知,没有C编译器会优化示例中的除法,是否允许编译器也存在疑问。
至于C ++,您应该请C ++专家来解释(我不是谁)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.