Как сделать #define с переменным числом аргументов?
От: Doc Россия http://andrey.moveax.ru
Дата: 21.10.05 00:21
Оценка:
Есть несолько функций с пременным числом аргументов вида
void MyFunc (TCHAR *pszMsg, ...);


Вопрос в том, что нужны они только время от времени. Можно конечно писать как
#ifdef DEBUG
MyFunc (TEXT("TEXT1"), TEXT("TEXT2"), TEXT("TEXT3"));
#endif

однако хочется сделать красиво, а именно
— через #define определить названия функций, если они нужны
— определить эти же #define как пустую строку, если они не нужны.
Т.е. что-то вроде

#define INCLUDE_MY_CODE // удалить при необходимости

#ifdef INCLUDE_MY_CODE
#define MyTestFuncDef MyFunc 
#else
#define MyTestFuncDef
#endif


вот только как сделать передачу списка параметров?
Re: Как сделать #define с переменным числом аргументов?
От: Doc Россия http://andrey.moveax.ru
Дата: 21.10.05 01:24
Оценка:
Вариант
#ifdef INCLUDE_MY_CODE
#define MyTestFuncDef MyFunc 
#else
#define MyTestFuncDef
#endif


работает, но меня мучают сомнения как бы это потом не вылилось.
Ведь когда
#define MyTestFuncDef
то в тексте от
MyFunc (TEXT("TEXT1"), TEXT("TEXT2"), TEXT("TEXT3"));
останется
(TEXT("TEXT1"), TEXT("TEXT2"), TEXT("TEXT3"));
компилятор проглатывает, но правильно ли это?
если в каачестве параметров будут исползоваться не const а функции — будут ли они отрабатывать?
Re: Как сделать #define с переменным числом аргументов?
От: fulltick  
Дата: 21.10.05 03:31
Оценка:
Здравствуйте, Doc, Вы писали:

Можно так попробовать:
#ifdef _DEBUG
void MyFunc( TCHAR* buf, ... );
#define MYFUNC(func) func
#else
#define MYFUNC(func)
#endif

И использовать
MYFUNC(MyFunc("%s %s", s, q));
Re[2]: Как сделать #define с переменным числом аргументов?
От: vopl Россия  
Дата: 21.10.05 05:23
Оценка:
Здравствуйте, Doc, Вы писали:
...

Вариант
#ifdef INCLUDE_MY_CODE
#define MyTestFuncDef MyFunc 
#else
inline void MyStub(...){};
#define MyTestFuncDef MyStub
#endif
Re: Как сделать #define с переменным числом аргументов?
От: bel_nikita  
Дата: 21.10.05 05:37
Оценка:
Здравствуйте, Doc, Вы писали:

Как сделать #define с переменным числом аргументов?


Может это: http://rsdn.ru/article/qna/cpp/define.xml
Re: Как сделать #define с переменным числом аргументов?
От: rus blood Россия  
Дата: 21.10.05 05:48
Оценка: 1 (1)
Здравствуйте, Doc, Вы писали:



#ifdef INCLUDE_MY_CODE
#define LOGOUT    MyFunc
#else
#define LOGOUT    1 ? (void)0 : MyFunc
Имею скафандр — готов путешествовать!
Re: Как сделать #define с переменным числом аргументов?
От: ДимДимыч Украина http://klug.org.ua
Дата: 21.10.05 06:54
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Есть несолько функций с пременным числом аргументов вида

Doc>
void MyFunc (TCHAR *pszMsg, ...);

[...skipped...]
Doc>однако хочется сделать красиво, а именно
Doc>- через #define определить названия функций,
[...skipped...]
Doc>вот только как сделать передачу списка параметров?

Для какого компилятора?
В gcc я например использую такую конструкцию для вывода отладочной информации:

#define PDEBUG(x, ...) \
        printf("%s:%i: %s(): "x"\n", __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re: Как сделать #define с переменным числом аргументов?
От: Аноним  
Дата: 21.10.05 07:32
Оценка: 1 (1)
Здравствуйте, Doc, Вы писали:

Doc>Есть несолько функций с пременным числом аргументов вида

Doc>
void MyFunc (TCHAR *pszMsg, ...);


Doc>Вопрос в том, что нужны они только время от времени. Можно конечно писать как

Doc>
#ifdef DEBUG
Doc>MyFunc (TEXT("TEXT1"), TEXT("TEXT2"), TEXT("TEXT3"));
Doc>#endif

Doc>однако хочется сделать красиво, а именно
Doc>- через #define определить названия функций, если они нужны
Doc>- определить эти же #define как пустую строку, если они не нужны.
Doc>Т.е. что-то вроде

Doc>
#define INCLUDE_MY_CODE // удалить при необходимости

Doc>#ifdef INCLUDE_MY_CODE
Doc>#define MyTestFuncDef MyFunc 
Doc>#else
Doc>#define MyTestFuncDef
Doc>#endif


Doc>вот только как сделать передачу списка параметров?


Есть еще один кривенький вариантик, потому что в одну строчку.

void assertvar( ...);

#ifndef _DEBUG
#define ASSERTVAR assertvar
#else
#define ASSERTVAR /##/
#endif

int f( void)
{
    ASSERTVAR( 1, 2, 3);
}


Если _DEBUG определен — то будет assertvar с переменным числом аргументов, иначе пустая строка.

С уважением,
Евгений Каратаев.
http://karataev.nm.ru
Re[2]: Как сделать #define с переменным числом аргументов?
От: Centaur Россия  
Дата: 21.10.05 14:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть еще один кривенький вариантик, потому что в одну строчку.


А>[сcode]

А>void assertvar( ...);

А>#ifndef _DEBUG

А>#define ASSERTVAR assertvar
А>#else
А>#define ASSERTVAR /##/
А>#endif

А>int f( void)

А>{
А> ASSERTVAR( 1, 2, 3);
А>}
А>[/cсode]

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

16.3.3/3: […] If the result [of concatenation] is not a valid preprocessing token, the behavior is undefined.

Re: Как сделать #define с переменным числом аргументов?
От: IROV..  
Дата: 21.10.05 14:47
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Есть несолько функций с пременным числом аргументов вида

Doc>
void MyFunc (TCHAR *pszMsg, ...);


Doc>Вопрос в том, что нужны они только время от времени. Можно конечно писать как

Doc>
#ifdef DEBUG
Doc>MyFunc (TEXT("TEXT1"), TEXT("TEXT2"), TEXT("TEXT3"));
Doc>#endif

Doc>однако хочется сделать красиво, а именно
Doc>- через #define определить названия функций, если они нужны
Doc>- определить эти же #define как пустую строку, если они не нужны.
Doc>Т.е. что-то вроде

Doc>
#define INCLUDE_MY_CODE // удалить при необходимости

Doc>#ifdef INCLUDE_MY_CODE
Doc>#define MyTestFuncDef MyFunc 
Doc>#else
Doc>#define MyTestFuncDef
Doc>#endif


Doc>вот только как сделать передачу списка параметров?



#    pragma once

namespace NError
{
    class CMessageError
    {
    public:
        inline CMessageError(const char * Function, int Line)
        :    m_Function(Function)
        ,    m_Line(Line)
        {
        }

        void operator() (const char * Message, ...);

    private:
        const char * m_Function;
        int m_Line;
    };
}

#    define ErrorMessage NError::CMessageError(__FUNCTION__,0)


Вот так я решал эту проблему
я не волшебник, я только учусь!
Re[3]: Как сделать #define с переменным числом аргументов?
От: Erop Россия  
Дата: 21.10.05 15:20
Оценка:
Здравствуйте, vopl, Вы писали:

V>Вариант

V>
#ifdef INCLUDE_MY_CODE
V>#define MyTestFuncDef MyFunc 
V>#else
V>inline void MyStub(...){};
V>#define MyTestFuncDef MyStub
V>#endif


Так делать плохо, так как аргументы всё равно будут вычисляться. А хотелось бы, насколько я понял, чтобы эти функции вели себя как стандартный assert -- компилировались в ничто.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Как сделать #define с переменным числом аргументов?
От: eton  
Дата: 28.11.05 18:56
Оценка:
А>>#ifndef _DEBUG
А>>#define ASSERTVAR assertvar
А>>#else
А>>#define ASSERTVAR /##/
А>>#endif
C>Невалидно. Ибо комменты рулят только до третьей фазы трансляции, а подстановка макросов выполняется в четвёртой. И
C>

16.3.3/3: […] If the result [of concatenation] is not a valid preprocessing token, the behavior is undefined.

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

вот случайно наткнулся в msdn на хороший способ:
__noop
Microsoft Specific

The __noop intrinsic specifies that a function should be ignored and the argument list unevaluated. It is intended for use in global debug functions that take a variable number of arguments.

The following code shows how you could use __noop:

// compiler_intrinsics__noop.cpp
// compile with or without /DDEBUG
#include <stdio.h>

#if DEBUG
   #define PRINT   printf
#else
   #define PRINT   __noop
#endif

int main() {
PRINT("\nhello\n");
}

END Microsoft Specific
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.