C - 强制字符串参数在只读内存中

标签 c gcc

我正在优化一些代码,我有一个这样的函数:

const char * gStrPtr = NULL;

void foo (const char *str) {
     gStrPtr = strdup(str);
}

截至目前,foo() 仅使用常量字符串调用。例如:

const char fooStr[]="Some really long string...";
foo(fooStr);

请注意,因为它总是用常量调用,所以我应该能够这样做:

void foo (const char *str) {
     gStrPtr=str;
}

但是,它打开了一根锋利的棍子:如果将来有人打破惯例,并尝试使用稍后释放的字符串的动态副本调用 foo(),它可能会导致 undefined行为。

我想知道是否有可能创建一个编译时甚至运行时检查来检查 str 是否在只读内存中以避免在路上进行昂贵的错误追踪。

注意:如果我假设 str 是一个字符串文字,那么我可以这样用一个宏来完成它:

#define foo(str)  foo_func("" str)

这将导致非字符串文字的编译错误。但它也不接受指向常量字符的指针。


编辑

我想我会在下面的讨论之后发布这个。 @CraigEtsy 指出使用 __builtin_constant_p,这是解决此问题的最佳方法(但可能足以满足我的需求)。我用它做了以下测试,并得到了这些结果:

void foo(const char *str) {
        if (__builtin_constant_p(*str))
                printf("%s is constant\n", str);
        else
                printf("%s is not constant\n", str);
}

const char globalArray[] = "globalArray";
const char *globalPtr = "globalPtr";

int main()
{
    const char localArray[]="localArray";
    const char *localPtr="localPtr";
    char localNonConst[]="localNonConst";
    foo("literal");     // constant
    foo(localArray);    // not constant
    foo(localPtr);      // constant
    foo(globalArray);   // constant
    foo(globalPtr);     // not constant
    foo(localNonConst); // not constant
}

当使用-O3 编译时,它给出了结果:

literal is constant
localArray is not constant
localPtr is constant
globalArray is constant
globalPtr is not constant
localNonConst is not constant

因此,对于我的特殊情况,我可以将 const char arr[]="str" 切换为 const char * arr="str",然后,在我的 foo() 中,我可以检查该值是否为常量,分配内存,如果不是则发出运行时警告(并标记一个标志,以便我知道稍后是否释放指针...)。

最佳答案

我认为没有任何合理的方法可以在运行时强制执行此操作,至少在没有比仅调用 strdup 昂贵多个数量级的机器的情况下是这样。

如果该函数只应该将不可变 字符串作为参数(这就是您正在寻找的词——不可变,从某种意义上说,它的生命周期将是进程生命周期的剩余部分,并且它的内容在其剩余生命周期内不会改变),这需要成为其接口(interface)契约的文档化部分。

关于C - 强制字符串参数在只读内存中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52319885/

相关文章:

c++ - 指针电阻

c++ - 如何在C/C++中获取HTML

c - C中的阻塞/非阻塞定时器

java - 如何使用 gcc 编译器或其他编译器生成 64 位 .dll。无法在 AMD 64 位平台上加载 IA 32 位 .dll

c++ - self 背后的理论和用法是什么,包括 C 和 C++ 中的源文件?

c++ - Eclipse/CDT/MinGW C++ 和奇怪的错误

c - Windows C 运行时 _close(fd) 不关闭文件

c - C编程,整数分布错误,找不到错误

c++ - 如何在MSVC中实现EXCLUDE_FIRST_ARGUMENT宏?

c - 存储在数组中的值在 OpenMP gcc 中更改