-D имя = определение и побитовый оператор - PullRequest
0 голосов
/ 18 февраля 2019

Я пытаюсь понять, как выполняется следующий расчет.

Например, если это моя терминальная команда

gcc ex2.c -D b+=2

Почему я получаю 5?

#include <stdio.h>

int main() 
{
#ifdef b
    printf("%d\n", 2 b | ~ 2 b);
#endif
    return 0;
}

2 b означает 2 * b?

~ 2 b означает 2 * b, а затем ~?

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Это странно, что это работает и выглядит как ошибка (или функция) из gcc и clang при разборе аргументов командной строки.

Похоже, gcc заменяет первый знак =в объявлении макроса пробелом.Таким образом, параметр:

-D b+=2

равен

#define b+ 2

, который, поскольку gcc имеет расширение для его интерпретации таким образом, равен

#define b + 2

, который делает вывод препроцессора:

printf("%d\n", 2 + 2 | ~ 2 + 2);

выражение 2 + 2 | ~ 2 + 2 равно (2 + 2) | ((~ 2) + 2) (см. приоритет оператора ), которое в twos дополняет системуравно 4 | (-3 + 2), что равно 4 | -1.На два дополнения -1 равно 0xff....ff, поэтому 4 | -1 равно 0xff...ff (как двоичное ИЛИ), что составляет -1.

0 голосов
/ 18 февраля 2019

компиляция с gcc ex2.c -D b+=2 определение b как +2, поэтому источник

#include <stdio.h>

int main() 
{
#ifdef b
    printf("%d\n", 2 b | ~ 2 b);
#endif
    return 0;
}

похож на

#include <stdio.h>

int main()
{

    printf("%d\n", 2 + 2 | ~ 2 + 2);

    return 0;
}

и для меня это печатает -1


, чтобы увидеть результат после предварительной обработки, используйте опцию -E:

/tmp % gcc ex2.c -E -D b+=2
<command-line>: warning: missing whitespace after the macro name
...
# 2 "ex2.c" 2

int main()
{

    printf("%d\n", 2 + 2 | ~ 2 + 2);

    return 0;
}
...