如何添加静态断言来检查变量是否是静态的?

发布于 2024-11-01 16:53:35 字数 269 浏览 0 评论 0原文

我有一个仅适用于静态局部变量的宏(因为它使用内联汇编表示法来提取有关变量的数据)。我需要一种方法来强制宏的输入确实是静态局部变量:

正确:

func f()
{
    static int x;
    my_macro(x);
}

不正确:

func f()
{
    int x;
    my_macro(x);
}

我使用 GCC for C(没有 C++)。

I have a macro which works well only on static local variables (since it uses inline assembly notation to extract data about the variable). I need a way to enforce that the input to the macro is indeed a static local variable:

correct:

func f()
{
    static int x;
    my_macro(x);
}

not correct:

func f()
{
    int x;
    my_macro(x);
}

I work with GCC for C (no C++).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

假面具 2024-11-08 16:53:35

您可以使用以下技巧:

#define ASSERT_LOCAL_STATIC(v) static void *p_ ## v = &v

void fn()
{
    int nonstatic_var = 0;
    static int static_var = 0;

    ASSERT_LOCAL_STATIC(static_var);
    ASSERT_LOCAL_STATIC(nonstatic_var);
}

GCC 对于非静态变量发出错误“初始化器元素不是常量”。

You can use following trick:

#define ASSERT_LOCAL_STATIC(v) static void *p_ ## v = &v

void fn()
{
    int nonstatic_var = 0;
    static int static_var = 0;

    ASSERT_LOCAL_STATIC(static_var);
    ASSERT_LOCAL_STATIC(nonstatic_var);
}

GCC issues an error "initializer element is not constant" for non-static variables.

孤君无依 2024-11-08 16:53:35

您也许可以通过使用静态变量和局部变量的地址来区分它们:

  • 静态变量存储在.BSS 或 .DATA 部分

  • 局部变量存储在堆栈中

例如,以下程序在我的系统上的输出

#include <stdio.h>

void f0() {
    int x = 0;
    printf("%p\n", &x);
}

void f1() {
    static int x = 0;
    printf("%p\n", &x);
}

int main() {
        f0();
        f1();

        return 0;
}

是这样的:

0x7fff1dc718dc
0x600900

每个部分和堆栈的放置位置取决于您平台的 ABI,但您可以使用块局部变量的地址来形成条件:

#include <stdio.h>

#define check(var) { \
        int ___ = 0; \
        printf("%s (%p): %s\n", #var, &var, (&var > &___)?"local":"static"); \
}

void f0() {
    int x = 0;
    check(x);
}

void f1() {
    static int y = 0;
    check(y);
}

int main() {
        f0();
        f1();

        return 0;
}

此输出:

x (0x7fff4b965afc): local
y (0x600978): static

警告:我不建议使用此“技巧”。这就是全部:一个诡计,一个在最不合时宜的情况下就会被破解的诡计。只需正确记录您的宏,并让使用它的人处理误用的后果即可。

You might be able to tell static and local variables apart by using their addresses:

  • Static variables are stored in either the .BSS or .DATA sections

  • Local variables are stored in the stack

For example the output of the following program on my system

#include <stdio.h>

void f0() {
    int x = 0;
    printf("%p\n", &x);
}

void f1() {
    static int x = 0;
    printf("%p\n", &x);
}

int main() {
        f0();
        f1();

        return 0;
}

is this:

0x7fff1dc718dc
0x600900

Where each section and the stack are placed depends on the ABI of your platform, but you could use the address of a block-local variable to form a condition:

#include <stdio.h>

#define check(var) { \
        int ___ = 0; \
        printf("%s (%p): %s\n", #var, &var, (&var > &___)?"local":"static"); \
}

void f0() {
    int x = 0;
    check(x);
}

void f1() {
    static int y = 0;
    check(y);
}

int main() {
        f0();
        f1();

        return 0;
}

This outputs:

x (0x7fff4b965afc): local
y (0x600978): static

Warning: I would not advise using this "trick". That's all it is: a trick, one that will break in the most unopportune of circumstances. Just document your macro properly and let the people who use it handle the aftermath of its misuse.

┈┾☆殇 2024-11-08 16:53:35

只需按照大多数 C 库使用的方式进行即可:告诉用户您的宏适用于静态变量,而其他任何内容的行为可能是未定义/意外的。

就像您也可以将 NULL 指针传递给 strdup() 等一样,这只会导致段错误,不强制执行不会产生大问题。

Simply do it in the way most C libraries use: Tell users that your macro works for static variables and the behavior for anything else may be undefined/unexpected.

Just like you can also pass NULL pointers to strdup() etc. which will result in nothing but a segfault there's not a big issue with not enforcing stuff.

知你几分 2024-11-08 16:53:35

我认为你无法在 ISO C 中区分这些情况。但是既然你已经提到你使用 GCC,那么可能有一些有用的内置伪函数。它们的名称均以 __builtin_ 开头,因此您应该仔细阅读 GCC 文档中的该列表。

http://www.google.com/search?q=gcc+builtin

好吧,我刚刚通读了整个内置部分,但没有找到任何东西。所以我觉得这确实是不可能的。

出于好奇,您想对宏做什么?

I think you cannot distinguish these cases in ISO C. But since you already mentioned that you use GCC there may be some helpful built-in pseudo functions. Their names all start with __builtin_, so you should read through that list in the GCC documentation.

http://www.google.com/search?q=gcc+builtin

Well, I just read through the whole built-ins section, and I didn't find anything. So I think it is really not possible.

What are you trying to do anyway with the macro, just out of curiosity?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文