V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Exxfire
V2EX  ›  C

我这段 C 代码可以在编译时候输出结构体的大小,你们还有什么好点子, show me the code!

  •  
  •   Exxfire · 9 天前 · 1011 次点击
    #include <stdio.h>
    
    struct X
    {
        int a;
        char c[10];
        short d;
    };
    char checker(int a)
    {
        (void)a;
        return '1';
    }
    
    #define STRINGIFY(x) #x
    #define TOSTRING(x) STRINGIFY(x)
    
    #define TEST(x)                                                              \
        do                                                                       \
        {                                                                        \
            char checkSizeOfInt[sizeof(x)] = {checker(&checkSizeOfInt)};         \
            _Pragma(TOSTRING(message("Value: " #x)))                             \
        } while (0);
    
    int main() {
        TEST(struct X);
        return 0;
    }
    
    8 条回复    2025-02-14 15:45:02 +08:00
    pipapa
        1
    pipapa  
       9 天前
    哪些编译器可以
    Exxfire
        2
    Exxfire  
    OP
       9 天前
    @pipapa 我用的 gcc 编译,其它没试。gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12)
    henix
        3
    henix  
       9 天前
    在 gcc 14 上修改之后会输出这些:

    ···
    test.c: In function 'main':
    test.c:21:51: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
    21 | char checkSizeOfInt[sizeof(x)] = {checker((int)&checkSizeOfInt)}; \
    | ^
    test.c:26:5: note: in expansion of macro 'TEST'
    26 | TEST(struct X);
    | ^~~~
    test.c:22:9: note: '#pragma message: Value: struct X'
    22 | _Pragma(TOSTRING(message("Value: " #x))) \
    | ^~~~~~~
    test.c:26:5: note: in expansion of macro 'TEST'
    26 | TEST(struct X);
    | ^~~~
    ···

    没看到什么结构体大小啊
    open9527
        4
    open9527  
       9 天前
    有什么用吗
    csfreshman
        5
    csfreshman  
       9 天前
    没什么用,执行和 3 楼一样
    Exxfire
        6
    Exxfire  
    OP
       9 天前
    @henix
    var_para_num_test.c: In function ‘main’:
    var_para_num_test.c:21:51: warning: passing argument 1 of ‘checker’ makes integer from pointer without a cast [-Wint-conversion]
    char checkSizeOfInt[sizeof(x)] = {checker(&checkSizeOfInt)}; \
    ^
    var_para_num_test.c:26:5: note: in expansion of macro ‘TEST’
    TEST(struct X);
    ^
    var_para_num_test.c:9:6: note: expected ‘int’ but argument is of type ‘char (*)[16]’
    char checker(int a)
    ^
    var_para_num_test.c:26:17: note: #pragma message: Value: struct X
    TEST(struct X);
    ^
    var_para_num_test.c:21:36: note: in definition of macro ‘TEST’
    char checkSizeOfInt[sizeof(x)] = {checker(&checkSizeOfInt)};
    yolee599
        7
    yolee599  
       8 天前 via Android
    https://stackoverflow.com/a/53884709
    但是有什么用呢?
    Exxfire
        8
    Exxfire  
    OP
       8 天前
    @yolee599 在编译阶段获取信息意味着不用等待程序编译完成,并执行,可以节省时间,提升效率。
    当然,我只是觉得这么干很有意思。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2556 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 10:53 · PVG 18:53 · LAX 02:53 · JFK 05:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.