在 C 中,const限定符使对象只读,但不是常量表达式。例如,不可能使用const int变量来确定数组的维度:
const int n = 10;
int arr [n]; /* Compile-time error */
Run Code Online (Sandbox Code Playgroud)
这其中的技术原因是什么?难道编译器在编译时就不可能知道该对象实际上有一个常量值吗?
我不认为我的问题与Can a const variable be used to statements the size of an array in C?完全相同。 因为我不是在问这是否可能(我的问题中明确指出这是不可能的),而是问为什么这是不可能的技术原因。
在下面奥拉夫的评论、这个答案和一些思考之后,我将尝试以这种方式总结和回答我的问题:
在 C 中,const对象不是编译时常量,因为它可能违反这两个要求:
首先,可以const在运行时初始化对象,如下所示:
int i;
scanf ("%d", & i);
const int n = i;
Run Code Online (Sandbox Code Playgroud)
所以这里我们违反了“编译时已知”的要求。
其次,正如Olaf指出的,const限定符意味着程序本身在声明-初始化之后不会修改对象的值。但是内存中对象的值仍然可以被程序本身之外的其他实体修改,因此这里我们不保证实际常量的要求。
如果此答案不正确或不完整,请批评。
我正在尝试将预编译头与 GCC 一起使用来加快编译过程。如果我直接从命令行启动编译,则会使用预编译头,但如果我尝试使用 makefile 来组织编译,则不会使用预编译头。
更具体地说,我尝试使用 GCC 8.1.0 编译文件main.cpp,使用预编译标头lib.hpp.gch作为 main.cpp 中的第一个标记包含的文件lib.hpp。
lib.hpp 预编译为
$ g++ -O2 -H -Wall -std=c++17 -c lib.hpp
Run Code Online (Sandbox Code Playgroud)
然后编译 main.cpp
$ g++ -O2 -H -Wall -std=c++17 -c main.cpp -o main.o
! lib.hpp.gch
...
Run Code Online (Sandbox Code Playgroud)
我可以从“!”中看到 实际使用的是预编译的 lib.hpp.gch。
如果我为此编写一个 makefile
CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17
main.o: \
main.cpp \
main.hpp \
lib.hpp
$(CXX) $(CXXFLAGS) \
-c main.cpp \
-o main.o
Run Code Online (Sandbox Code Playgroud)
然后使用 make,我希望预编译头的用法相同
但它失败了,从“x”可以看出:
$ make
g++ -O2 -H …Run Code Online (Sandbox Code Playgroud)