在C语言中,编译时评估什么?

问题描述

| 我可以在编译时将变量设置为某个值吗? 如果我有一个函数可以在程序初始化时更改所有ѭ0的值,那么如果我在编译时执行此操作,则可以节省大量时间并使用处理器,可以吗? 我了解到静态和全局变量将其值初始化为
0
。如果我声明像
static int a = 3;
,数字the3ѭ会在编译或运行时分配吗?如果是的话,也可以组合文字吗?我怎么知道这是真的吗? (我不知道该如何使用调试。) 我也了解了常数C表达式,但是我不明白这是什么。这对我有用吗?它是什么? 更新:我只问我是否可以在编译时更改一个变量的值!!! (还有其他一些事情...)     

解决方法

优化的一些基本原则: 仅优化已测量的(概要分析)瓶颈,不要浪费时间优化虚构或假设的问题,除非您是正在重新实现已知的计算时间问题的主题专家 除非处于循环中,否则不要优化任何东西 但是要回答你的问题... 始终在编译时: 静态初始化
#if
和其他预处理程序宏表达式 通常在编译时: 任何仅涉及常量的表达式     ,如果我理解您的问题,您会对哪种变量放入哪种数据段感到好奇。 未初始化的全局变量和函数级的“ 5”变量进入“ 6”部分,实际上这只是目标文件中的一个数字,告诉链接器/加载器在加载程序或库时为该部分留出多少空间:
$ readelf --sections /bin/sh
There are 28 section headers,starting at offset 0x195e8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
...
  [26] .bss              NOBITS           0000000000619500  00019500
       0000000000002bd0  0000000000000000  WA       0     0     32
那0x2bd0 == 11216字节将在运行时为未初始化的变量保留。 初始化的全局变量存储在
data
rodata
节中:
$ readelf --sections /bin/sh
There are 28 section headers,starting at offset 0x195e8:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
...
  [16] .rodata           PROGBITS         0000000000412de0  00012de0
       0000000000003482  0000000000000000   A       0     0     32
...
  [25] .data             PROGBITS         0000000000619300  00019300
       0000000000000200  0000000000000000  WA       0     0     32
抱歉,我忘记了编译器/链接器用来确定哪些变量进入只读部分以及哪些变量进入读/写部分的确切规则。但是足以说链接器会将页面保护设置为“ 9”部分为只读,而尝试写入此部分将产生页面错误并可能终止程序。
char *string = \"hello world\"; /* \"hello world\\0\" goes into rodata
                                 char *string goes into data */
我希望任何仅基于文字整数,浮点数和“ 13”运算的计算都将在编译时进行计算。 一个非常小的例子:
$ cat test.c
int i;
int main(int argc,char *argv[]) {
    return 0;
}
$ gcc -o test test.c
$ size test
   text    data     bss     dec     hex filename
   1044     496      24    1564     61c test
C库带来了很多额外的负担。但是请注意,当我们初始化
i
,减小happens6ѭ大小,增大ѭ8goes大小时会发生什么:
$ cat test.c
int i=1+2;
int main(int argc,char *argv[]) {
    return 0;
}
$ gcc -o test test.c
$ size test
   text    data     bss     dec     hex filename
   1044     500      16    1560     618 test
$ 
我假设在系统上将“ 6”限制为“ 20”的倍数,因为它是兼容AMD64的CPU。其他系统可能需要
4
的倍数。
$ cat test.c
int i=sizeof(int);
int main(int argc,char *argv[]) {
    return 0;
}
$ gcc -o test test.c
$ size test
   text    data     bss     dec     hex filename
   1044     500      16    1560     618 test
$ 
请注意,切换到
sizeof(int)
不会增加
text
(可执行代码)的大小,也不会改变
data
的大小。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...