2012-10-15 34 views
0

有一天,我正在将一个用C99标准编写的程序转换成C11。基本上动机是使用MSVC的代码,但它是用Linux编写的,并且大部分都是使用默认的GCC行为编译的。在代码转换过程中,我发现你不能在任何语句后去除函数的变量,也就是说你必须在函数的顶部声明它们。使用C99和C11时的效率问题。

但我的问题是,它不会违反有效的编程规则,变量应该在其使用附近进行声明,以使其最大化缓存命中?例如,在一个200 LOC的大函数中,我想在函数的最后使用一些大的静态查找数组。在使用导致更多缓存命中之前不会声明并初始化它?还是我简单地缺少C11 C语言标准的一些基本点?

+0

C2011(我恨名字C11)允许与代码混合的声明。 *我明白微软的编译器只能理解C89,可能只有一些扩展。* – pmg

+1

这与C89有关,在这里你不能在同一个块中的语句之后放置声明。 C99和C11中不再存在此要求。 – ouah

+1

MSVC不支持C11。也许你的意思是C89? – ecatmur

回答

4

您似乎对编译程序的哪个版本的标准有些疑惑。 AFAIK,MSVC不支持任何更新的C标准。

但是,要回到您的问题的核心,这不是一个效率问题。只要程序的可观察行为不改变,编译器就可以按照自己的喜好重新排列语句。因此,一个现代编译器会在第一次使用之前总是触及一个新的变量。

+0

除非涉及volatile,否则可能在函数的开头有一个纯声明,根本不可访问该变量。 –

+0

@BenVoigt,'volatile'对于语句的重新排序没有太大的影响,我想。它只强制为每个使用它的表达式重新加载一个对象。什么可能影响编译器可以推断出的是别名。但是一般来说,如果你在你的程序开始时声明一个int变量,甚至初始化它,编译器可以在第一次使用该变量之前的任何地方进行初始化。 –

+1

* other *变量的读取和写入不能跨越易失性访问进行移动。 –

2

变量声明出现的位置对缓存行为没有影响。只是有一个声明不会触及内存。

但是,您可能需要将初始化划分为单独的赋值,以确保在函数的开头(靠近)没有引起内存访问的初始化程序。