Имейте макрос, 'возвращают' значение

Я использую макрос, и я думаю, что он хорошо работает -

#define CStrNullLastNL(str) {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}}

Таким образом, это работает для обнуления последней новой строки в строке, действительно его используемый для обрубания разрыва строки, когда на этом оставляет fgets.

Так, я задаюсь вопросом, могу ли я "возвратить" значение от макроса, таким образом, как это можно назвать

func( CStrNullLastNL( cstr ) ) ;

Или я должен буду записать функцию

19
задан bobobobo 20 April 2010 в 22:34
поделиться

7 ответов

Чтобы макрос «возвращал значение», сам макрос должен быть выражением. Ваш макрос - это блок операторов, который не может быть вычислен как выражение.

Вам действительно следует написать встроенную функцию . Это будет так же быстро и намного удобнее в обслуживании.

31
ответ дан 30 November 2019 в 01:53
поделиться

Макросы не возвращают значения. Макросы предписывают препроцессору заменить все, что находится после #define , тем, что находится после элемента после #define . Результат должен быть действительным C ++.

Вы просите, как сделать следующее действительным:

func( {char* nl=strrchr(str,'\n'); if(nl){*nl=0;}} );

Я не могу придумать хороший способ превратить это во что-то действительное, кроме как просто сделать это реальным вызовом функции. В этом случае я не уверен, почему макрос лучше встроенной функции. Кажется, это именно то, о чем вы действительно просите.

6
ответ дан 30 November 2019 в 01:53
поделиться

Я дал +1 Майку, потому что он на 100% прав, но если вы хотите реализовать это как макрос,

char *CStrNullLastNL_nl; // "private" global variable
#define nl ::CStrNullLastNL_nl // "locally" redeclare it
#define CStrNullLastNL( str ) ( \
    ( nl = strrchr( str, '\n') ), /* find newline if any */ \
    nl && ( *nl = 0 ), /* if found, null out */ \
    (char*) nl /* cast to rvalue and "return" */ \
OR  nl? str : NULL /* return input or NULL or whatever you like */
)
#undef nl // done with local usage
4
ответ дан 30 November 2019 в 01:53
поделиться
#define CStrNullLastNL(str) ({ \
    char* nl=strrchr(str,'\n');\
    if(nl){*nl=0;} \
    nl; \
})

должно работать.

Редактировать: ... в GCC.

26
ответ дан 30 November 2019 в 01:53
поделиться

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

3
ответ дан 30 November 2019 в 01:53
поделиться

Вы можете использовать оператор запятой? Упрощенный пример:

#define SomeMacro(A) ( DoWork(A), Permute(A) )

Здесь B = SomeMacro (A) «возвращает» результат Permute (A) и присваивает его «B».

5
ответ дан 30 November 2019 в 01:53
поделиться

Если вы действительно хотите это сделать, получите компилятор, поддерживающий C ++ Лямбда-выражения в стиле 0x:

#define CStrNullLastNL(str) [](char *blah) {char* nl=strrchr(blah,'\n'); if(nl){*nl=0;} return blah;}(str)

Хотя, поскольку CStrNullLastNL в основном является функцией, вам, вероятно, следует переписать ее как функцию.

5
ответ дан 30 November 2019 в 01:53
поделиться
Другие вопросы по тегам:

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