我只是想知道以下是否可以被认为是安全的做法:
void some_func(void) {
const char * foo;
if (SOME_MACRO()) {
char * foo_buf[20];
snprintf(foo_buf,sizeof(foo_buf),"blah_%d",some_global);
foo = foo_buf;
} else {
foo = "some constant string";
}
// do a bunch of other stuff here...
printf("%s\n", foo);
}
这假设 foo_buf
中的内存在 block 作用域之外仍然有效(且未更改)。我担心是否存在编译器在 block 退出时丢弃或覆盖 block 特定内存的情况。我希望在 block 中而不是在全局范围内声明的原因是,在某些平台上,SOME_MACRO()
会解析为一个常量,而在其他平台上,则解析为一个表达式,因此在某些情况下可以优化 if block 。
最佳答案
这是UB。
提升 char * foo_buf[20];
不应该给你更糟糕的代码。无论如何,所有函数的局部变量都可能分配在顶部,并且编译器能够很好地消除从未使用过的局部变量。
尝试编译:
#define UP 0
#define CONST 1
#include <stdio.h>
#if CONST
#define SOME_MACRO() 0
#else
int SOME_MACRO(void);
#endif
int some_global;
void some_func(void) {
const char * foo;
#if UP
char foo_buf[20]; //fixed from char *foo_buf[20];
#endif
if (SOME_MACRO()) {
#if !UP
char foo_buf[20]; //fixed from char *foo_buf[20];
#endif
snprintf(foo_buf,sizeof(foo_buf),"blah_%d",some_global);
foo = foo_buf;
} else {
foo = "some constant string";
}
// do a bunch of other stuff here...
printf("%s\n", foo);
}
将 CONST 设置为 0 或 1,然后将 UP 更改为介于 0 和 1 之间。
使用 gcc、clang 或 icc 移动声明(通过更改 UP
)即使在 -O0
也没有区别:https://gcc.godbolt.org/z/z9jnQD .
关于c - block 作用域缓冲区在 c 中的 block 之外是否有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56463477/