GCC C Preprocessor

Table of Contents

1. GCC C Preprocessor

1.1. #line

test.c:

float foo(float x) {
    if (x > 0.0) {
#line 1 "test.txt"
        return x + 1.0;
    }
    return 0.0;
}

#line 2 "test.txt"
int main(int argc, char *argv[]) {
    foo(10.9);
    printf("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    return 0;
}

test.txt

line 1
line 2
line 3
line 4
line 5
line 6
line 7
line 8
line 9
line 10
$> gcc test.c -O0 -g
$> gdb ./a.out

(gdb) b main
Breakpoint 1 at 0x117d: file test.txt, line 2.
(gdb) r
Starting program: /home/sunway/download/a.out 

Breakpoint 1, main (argc=0, argv=0x7fffffffbed0) at test.txt:2
2       line 2
(gdb) n
3       line 3
(gdb) n
4       line 4
(gdb) c
Continuing.
test.txt main 4
[Inferior 1 (process 13034) exited normally]

1.2. macro concatenation

https://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

使用 `##` 主要目的是用宏参数展开成另一个 token, 例如

#define xx 2
#define X(x, y) x##y
int main(int argc, char *argv[]) {
    printf("%d\n", X(x, x));
}

如果 concat 后不是一个合法的 token, 则会报错, 例如

#define X(x, y, z) x##y##z
int main(int argc, char *argv[]) {
    /* x##y 后为 1+, 不是合法的 token */
    printf("%d\n", X(1, +, 2));
    /* x##y 后为 12, 是合法的 token */
    printf("%d\n", X(1, 2, 3));
}

如果只是普通的拼接(不生成 token), 并不需要使用 `##`

#define X(x, y) x y;
int main(int argc, char *argv[]) {
    X(return, 0);
}

Backlinks

GCC (GCC > C Preprocessor): C Preprocessor

Author: [email protected]
Date: 2022-04-02 Sat 16:04
Last updated: 2023-05-06 Sat 17:46

知识共享许可协议