Макрос: значение void не игнорируется, как и должно быть

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

#define FALSE 0
#define TRUE !FALSE

#define CASSERT(predicate) \
 ({ \
    if ((predicate)) \
    { \
        (TRUE); \
    }else\
    { \
        __debugbreak(); \
       (FALSE); \
    }})

Я хочу использовать это вот так

if (!CASSERT(X==Y)){}

это ошибка, которую я получаю

error: void value not ignored as it ought to be

error: could not convert '<statement>' from 'void' to 'bool'

Я попробовал несколько вариантов этого кода, и ни один из них не работает! вывод CASSERT — это пустая функция!

Вместо { if (predicate) ... else ...}, может быть, (predicate) ? ... : ...?

chux - Reinstate Monica 12.08.2024 07:51

В новом коде использования используйте stdbool.h вместо доморощенных логических значений. Есть ли причина, по которой вам нужны !TRUE и !!FALSE? Рассмотрите возможность инвертирования значения предиката или замены двух выражений условного оператора.

Allan Wind 12.08.2024 08:03

Если вы пытаетесь использовать выражения операторов GCC (gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html), то ваш синтаксис неверен - переменная с результирующим значением должна быть последней в блоке кода.

qrdl 12.08.2024 08:24

@qrdl Да, подтверждаю, в последнем блоке это тоже работает if (!(predicate)) { __debugbreak(); } (predicate); Спасибо

ma1169 12.08.2024 08:32

@ ma1169 ma1169 Было бы лучше использовать локальную переменную в выражении оператора, чтобы параметр макроса predicate расширялся только один раз. Например. #define CASSERT(predicate) ({ int result__ = (predicate) ? TRUE : FALSE; if (!result__) { __debugbreak(); } result__; }).

Ian Abbott 12.08.2024 12:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Выполните замену текста самостоятельно.

if (!CASSERT(X==Y)){}

Становится:

if (!{
    if ((X==Y)) {
        (!0);
    }
    else {
        __debugbreak();
        (0);
    }}) {}

Это похоже на действительный код C? Это не так, поскольку условный оператор не является выражением, возвращающим логическое значение.

Вы можете использовать условное выражение с оператором запятой для упорядочивания __debugbreak() и FALSE. Что-то вроде:

#define CASSERT(PRED) ((PRED) ? TRUE : (__debugbreak(), FALSE))

Теперь ваш код расширится до:

if (!((X==Y) ? !0 : (__debugbreak(), 1))) {}

Это действительный код C.

Я думаю, что оригинал на самом деле расширяется до if (!({if ((X==Y)){{!0;}else {__debugbreak();0;}})), в котором используется расширение GCC «выражение оператора» ({}), где последний оператор в блоке может возвращать значение. Проблема в том, что выражение оператора исходного кода не содержит последнего оператора, возвращающего значение.

Ian Abbott 12.08.2024 12:27

Другие вопросы по теме