我得到了这个代码:
clock_t record[2][15];
char *blockName[15];
int count = 0;
#define BEGIN(block_name) \
do{ \
blockName[count] = #block_name;\
record[0][count++] = clock(); \
}while( 0 ) \
#define END(block_name) \
do{ \
for( int i = 0; i < count; i++ ) \
if( #block_name == blockName[i] ){ \
record[1][i] = clock(); \
break; \
} \
}while( 0 ) \
#define RESULT \
do{ \
for( int i = 0; i < count; i++ ) \
printf( "block %s costs %f seconds\n", blockName[i], \
(double)(record[1][i]-record[0][i])/ CLOCKS_PER_SEC ); \
}while( 0 ) \
当我们在 -Wall
上编译代码时,我收到警告:
警告:与字符串文字比较会导致未指定的行为 [-Waddress]
我知道一个技巧,即包含相同内容的字符串存储在相同的内存中。
因此,我编写了 if(#block_name == blockName[i]) 行来比较两个字符串。
但不知道是否总是如此。
该警告是否意味着该技巧不适用于所有平台?
最佳答案
不,这实际上取决于编译器,相同的字符串文字在编译后是否会指向相同的地址(因此是未定义的行为)。因此,简单的地址比较通常不足以确保两个字符串相同,即使它们都硬编码在同一个源文件中。
例如,Microsoft 将此称为“字符串池”,并允许您专门启用或禁用它。
以下简单代码为例:
const char *text1 = "Hello World!";
const char *text2 = "Hello World!";
printf("Hello World!");
如果不进行优化,生成的可执行代码可能最多包含字符串“Hello World!”的三个实例。
根据编译器(以及在 MSVC 的情况下是否启用“字符串池”),您最终可能会得到不同的内存布局:
针对大小进行了优化(和/或启用了字符串池):
(其他数据)Hello World!\0(其他数据)
未针对大小进行优化(和/或禁用字符串池):
(其他数据)Hello World!\0Hello World!\0Hello World!\0(其他数据)
当然,实际布局可能仍然略有不同。中间可能还有其他内存(即使只是用于填充)。
一般建议:永远不要假设任何有关内存对齐或内存地址的事情,除非您专门定义了布局(例如作为struct
的一部分)。
至于您的实际代码问题,我假设您想要一些简单的方法来测量时间?如果是这样,为什么不使用串联 (timer ## block_name
) 在运行时创建值?
关于c - 在C中,具有相同内容的字符串总是存储在相同的内存中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21825841/