如何解决在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
的大小。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。