对于调试日志记录,我经常看到并使用类似的东西
#ifdef DEBUG
#define DLOG(fmt, args...) printf("%s:%d "fmt,__FILE__,__LINE__,args)
#else
#define DLOG(fmt, args...)
#endif
Run Code Online (Sandbox Code Playgroud)
但在很多地方,我看到第二个#define被替换了
#define DLOG(fmt, args...) do {} while (0)
Run Code Online (Sandbox Code Playgroud)
特别是,有这个答案,对同一问题的另一个答案的评论表明,问题将出现在像
if (condition)
DLOG("foo");
Run Code Online (Sandbox Code Playgroud)
虽然我的快速测试表明,行中产生的分号本身将作为条件内的无操作语句.
是一个或其他的什么和do {} while (0)好?如果是这样,为什么?还有其他更好的东西吗?
当我有一个应该重复用作参数realloc并保存其返回值的指针时,我知道realloc如果无法进行分配,则不会触及旧对象,返回NULL. 我是否还应该担心以下结构中的旧对象:
int *p = (int *)malloc(sizeof(int *));
if (p = (int *)realloc(p, 2 * sizeof(int *)))
etc...
Run Code Online (Sandbox Code Playgroud)
现在,如果realloc成功了,我需要free(p)在完成后进行。当realloc失败时,我已指定它返回NULL并且p不free(p)执行任何操作(因为它是 a free(NULL))。同时(根据标准)旧对象不会被释放。p那么我是否应该有一个(例如)的副本int *last_p = p;来跟踪旧对象,以便free(last_p)在realloc失败时可以?
我对C++比较陌生,我正在上课.我们的班级被分配了一个实验室,我的老师说实验室的写作有点难以理解; 但是,他没有对实验室的记录做任何改动.所以,我遇到了实验室的这一部分:
定义预处理器宏
长期约定大写宏名称,此宏名称必须为TRACE_FUNC.宏有一个参数,当您将宏应用于代码时,该符号将被函数名替换.宏的开头看起来像这样:
Run Code Online (Sandbox Code Playgroud)#define TRACE_FUNC( symbol ) replacement-text`并且预处理器将替换源代码中存在TRACE_FUNC(sym)字符串的替换文本,并将符号提供给该替换.
注意:#define语句必须全部在一条逻辑行上.为了保持长度可管理,您可以在行尾用反斜杠转义换行符; 这将使预处理器保持满意,同时允许您跨越多行的定义.
对于本练习,替换文本必须是完整的语句,包括终止分号.
替换文本必须是输出语句,用于打印符号,后跟调用的text().和标准输出的换行符.您可以复制和修改warning.cpp源文件中的一个输出语句.
warning.cpp只是我们正在使用的文件,TRACE_FUNC它被放置在头文件中.
所以,我读了几遍,我不是百分之百确定它在问什么.从某种角度来看,似乎要求我创建一个名为TRACE_FUNC的宏.如果你以另一种方式看它,它要求我使用宏TRACE_FUNC.所有这一切都很好,但我根本不知道如何使用TRACE_FUNC,我无法在任何地方找到任何文档,我不知道如何创建宏.当我寻求帮助时,我的老师只是说.单词,而不是非常有用的单词,因为它是一个非常曲折,令人困惑的答案,没有解释TRACE_FUNC实际上是什么.
基本上,我老师说的只是内部符号TRACE_FUNC需要是源代码中某个函数的名称.举一个例子,假设我们foo()在警告中有一个函数,那么符号应该是foo()(或foo,我也不确定),从他的解释.此外,在替换文本中,如果我放在#符号前面,显然名称本身将被替换.我认为这应该表示预处理器指令.为什么我应该在这里使用它?
无论如何,做我老师所说的几乎没有任何作用.这条线都没有
#define TRACE_FUNC( foo() ) #foo() called. ;
也不是这一行
#define TRACE_FUNC( foo ) #foo () called. ;
替换任何文本,我很确定是#define指令的操作.因此,我必须以错误的方式应用我的老师所说的内容,但我不知道为什么这是错的或如何解决它.
所以,我的问题.是TRACE_FUNC实际上是一个宏,如果是这样,有它的任何文件,我可以读?或者我应该创作TRACE_FUNC,如果是这样,我该怎么做呢?
使用iphone sdk 4.0我想从这个宏中删除函数名称的东西,但我正在努力
#define LOG(fmt, ...) NSLog((@"%s " fmt), __PRETTY_FUNCTION__,##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
我试过了
#define LOG(fmt, ...) NSLog((@"%s " fmt), ##__VA_ARGS__)
Run Code Online (Sandbox Code Playgroud)
但这会导致崩溃!!
我希望能够像这样记录
LOG("text to log");
LOG("text to log with param %d", param); etc
Run Code Online (Sandbox Code Playgroud) 这是循环,不是循环,还是循环而不是循环?如果你在计算程序中的循环次数,你会算这个吗?
do {
...
}while(0);
Run Code Online (Sandbox Code Playgroud)
我很好奇,因为我正在与一个有一个项目的人一起工作,这个项目要求他计算程序中的循环次数.
#define swap(a,b) a = a ^ b; b = a ^ b; a = a ^ b;
int main()
{
swap(a,b)
}
Run Code Online (Sandbox Code Playgroud)
给出正确答案。
#define swap(a,b) (a = a ^ b; b = a ^ b; a = a ^ b;)
int main()
{
swap(a,b)
}
Run Code Online (Sandbox Code Playgroud)
给出编译错误:“;”之前为“ expected')' 令牌”
#define swap(a,b) ({a = a ^ b; b = a ^ b; a = a ^ b;})
int main()
{
swap(a,b); //note the semicolon at the end, without that the compiler gives …Run Code Online (Sandbox Code Playgroud) 我有一个以下形式的结构:
struct foo {
bool has_value;
int value;
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个宏,它可以用来赋值,如下所示:
ASSIGN(foo) = 0;
or
ASSIGN(foo) += 5;
Run Code Online (Sandbox Code Playgroud)
当宏为:
#define ASSIGN(s) \
s->has_value = true; s->value
Run Code Online (Sandbox Code Playgroud)
然而,宏并不安全。在下面的示例中,if将“吃掉”宏的第一部分ASSIGN。
if (cond)
ASSIGN(foo) += 5;
Run Code Online (Sandbox Code Playgroud)
关于如何确保安全有什么建议ASSIGN 吗?
在一个软件项目(一些旧的C编译器)上,我们有很多变量必须保存正常和反转.
有人知道如何制作这样的宏吗?
SET(SomeVariable, 137);
Run Code Online (Sandbox Code Playgroud)
哪个会执行
SomeVariable = 137;
SomeVariable_inverse = ~137;
Run Code Online (Sandbox Code Playgroud)
编辑:
最好的解决方案似乎是:
#define SET(var,value) do { var = (value); var##_inverse = ~(value); } while(0)
Run Code Online (Sandbox Code Playgroud)
谢谢你的回答
在你说它重复之前,我已经读过:如何将可变数量的参数从一个函数传递到另一个函数?
我有这样的功能:
void tlog_function(t_log* logger, const char* message_template, ...) {
pthread_mutex_lock(&loggerLock);
log_function(logger, message_template, ...); // What I want to do..
pthread_mutex_unlock(&loggerLock);
}
Run Code Online (Sandbox Code Playgroud)
而另一个这样的功能,不是我的,我在第三方库中使用它:
void log_function(t_log* logger, const char* message_template, ...);
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我想要做的只是在这个函数中添加一个互斥锁以使其具有线程安全性,我知道我可以使用va_list但在这种情况下我无法更改第二个函数的代码,因为它在库中我只有.h文件.
那么,有没有办法实现这一目标?
我有一个C函数,该函数调用其他函数,每个函数返回int,0如果!= 0 ,则为OK或错误代码。该函数如下所示:
int myfunc()
{
int err;
err = func1(arg1);
if (err != 0) {
return err;
}
err = func2(arg2, arg3);
if (err != 0) {
return err;
}
err = func3(arg4, arg5);
if (err != 0) {
return err;
}
err = func4();
if (err != 0) {
return err;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我有很多样板代码:
err = some_func();
if (err != 0) {
return err;
}
Run Code Online (Sandbox Code Playgroud)
是否可以编写一些宏来简化它?就像是:
#define TRY() ???
int myfunc()
{ …Run Code Online (Sandbox Code Playgroud) 在阅读我的小组项目的代码时,我遇到了许多DEFINE,其中一些似乎很奇怪.要概括它,请查看以下2个示例.
例1:
#define SNPRINTF(dst, fmt, arg...) snprintf(dst, sizeof(dst), fmt, ##arg)
Run Code Online (Sandbox Code Playgroud)
"##"在这种情况下意味着什么?我试图删除他们两个,并写这样的代码 "字符BUF [1024]的snprintf(buf中," %S%S " "ABCD", "EFG");" 这产生了相同的结果.所以"##"似乎毫无用处,对我没有任何伤害.
例2:
#define CLOSE(fd) do { \
if (-1 != (fd)) { \
close(fd); \
(fd) = -1; \
} \
} while (0)
Run Code Online (Sandbox Code Playgroud)
有必要将内部代码填充到do{}while(0)语句中吗?什么用途?
可能重复:
为什么在C/C++宏中有时会出现无意义的do/while和if/else语句?
做{...}而(0)有什么好处?
探索libusb-1.0.9源代码,我找到了这样的line(./os/poll_windows.c:78):
#define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
Run Code Online (Sandbox Code Playgroud)
至于我,这是一样的:
#define CHECK_INIT_POLLING if(!is_polling_set) init_polling();
Run Code Online (Sandbox Code Playgroud)
是否有理由循环该表达式?
更新:
在答案之后,我仍然无法意识到会出现什么问题,以下示例有助于:
#include <stdio.h>
#define TEST if(test) foo();
#define TEST_DO do { if(test) foo(); } while(0)
int test = 1;
void foo() {
printf("%s", "Foo called");
}
int main(int argc, char** argv) {
if(argc > 1) TEST_DO; /* LINE 12 */
else printf("%s", "skipping...");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果放在TEST第12行,编译器将给出错误"error: ‘else’ without a previous ‘if’".
希望,这会有所帮助.
#define SWAP(a,b) { a^=b ; b^=a ; a^=b; }
if (x < 0)
SWAP(x,y);
else
SWAP(y,x);
Run Code Online (Sandbox Code Playgroud)
我上面给出的代码不起作用.编译时出现以下错误.
trial.c:3:1: error: expected identifier or '(' before 'if'
trial.c:5:1: error: expected identifier or '(' before 'else'
Run Code Online (Sandbox Code Playgroud)
我试图弄清楚它不起作用的确切原因.预处理器按如下方式扩展宏
if (x < 0)
{
x^=y ;
y^=x ;
x^=y ;
};
else
{
y^=x ;
x^=y ;
y^=x ;
};
Run Code Online (Sandbox Code Playgroud)
我怀疑花括号末端的分号是导致问题的原因.但我不确定.谁能解释一下?