Различия в Макросе ## оператор конкатенации между Visual C++ и gcc

Возможно, потому что имеет смысл чисто выходить с кодом статуса от main() метод. В Java мы должны эмулировать это использование System.exit(), который не является всем этим корректным.

5
задан Brian Tompsett - 汤莱恩 11 February 2016 в 20:12
поделиться

3 ответа

Возможно, Visual C ++ вставляет пару пробелов вместе, чтобы образовалось другое. Не то чтобы пробелы были токенами, но они позволили бы вашему коду работать.

object.member - это не токен, это три токена, поэтому вам не нужно вставлять токены для реализации описываемого макроса. Просто удалите '##', и он будет работать везде.

[Edit: только что проверено, и результат использования ## для формирования чего-то, что не является допустимым токеном, не определен. Итак, GCC разрешено отклонить его, а MSVC разрешено игнорировать его и не выполнять вставку, насколько я могу судить.]

7
ответ дан 18 December 2019 в 10:47
поделиться

Согласно Стандарту C, результат оператора предварительной обработки « ## » должен быть «токеном предварительной обработки», иначе результат не определен (C99 6.10.3.3 ( 3) - Оператор ##).

Список токенов предварительной обработки (C99 6.4 (3) - Лексические элементы):

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

GCC сообщает вам, что вы входите в неопределенную территорию. MSVC молча доволен результатом undefined (это то, чего вы в значительной степени ожидали).

Обратите внимание, что если вы все равно не создаете ни одного токена, вам не нужен оператор вставки токена. Вообще (я уверен, что есть)

5
ответ дан 18 December 2019 в 10:47
поделиться

Из документации препроцессора gcc c :

Однако два токена, которые не вместе сформировать действительный токен не может быть вставлен вместе.

structure.member не является отдельным токеном.

В этом случае вам не нужно использовать оператор ## (объединение токенов). Вы можете просто удалить это. Вот пример, протестированный с gcc 4.2.4 в Linux:

#include <stdio.h>

#define STRUCTMEMBER(Member, Value) GlobalStructInstance.Member = Value

struct {
    const char* member1;
}GlobalStructInstance;

int main(void)
{

    STRUCTMEMBER(member1, "Hello!");

    printf("GlobalStructInstance.member1 = %s\n",
           GlobalStructInstance.member1);

    return 0;
}
4
ответ дан 18 December 2019 в 10:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: