我知道在C99(以及通过GNU扩展)中添加了可变参数宏.我一直想知道在ANSI C中是否有一个不错的选择.
我想出了类似的东西,但它仍然有点尴尬:
void log_info(const char *file, int line, const char *fmt, ...)
{
#ifdef DEBUG
va_list ap;
char newfmt[1024] = { 0 };
va_start(ap, fmt);
sprintf(newfmt, "[INFO] (%s:%d): %s\n", file, line, fmt);
vfprintf(stderr, newfmt, ap);
va_end(ap);
#endif
}
Run Code Online (Sandbox Code Playgroud)
所以这可以像这样调用:
log_info(__FILE__, __LINE__, "info message: %s %d", "helloworld", 12);
Run Code Online (Sandbox Code Playgroud)
这种方法没有任何问题,但是我想知道是否有更好的方法呢?例如.无需每次都指定文件/行.
我很感激任何反馈.:)
编辑:通过ANSI C这里我的意思是C89.
编辑:下面的答案很好,但我相信它需要运行打印命令twise它可能会带来一些线程安全问题.另一种选择可能是使用define来最小化输入(也非常难看):
#define __FL__ __FILE__, __LINE__
Run Code Online (Sandbox Code Playgroud)
然后运行命令,如:
log_info(__FL__, "info message: %s %d", "helloworld", 12);
Run Code Online (Sandbox Code Playgroud) 我遇到了一个奇怪的问题,下面的代码无法编译:
func main() {
var val reflect.Value
var tm time.Time
if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {
panic(err)
}
val = reflect.ValueOf(tm)
fmt.Println(val, tm, reflect.TypeOf(tm))
}
Run Code Online (Sandbox Code Playgroud)
有错误(代码是linter推荐的):
$ go run main.go
# command-line-arguments
./main.go:13:5: tm declared and not used
Run Code Online (Sandbox Code Playgroud)
注意tm确实使用了变量.
但是,如果我添加一个else块 - 一切都按预期编译:
func main() {
var val reflect.Value
var tm time.Time
if tm, err := time.Parse(time.RFC3339, "2018-09-11T17:50:54.247Z"); err != nil {
panic(err)
} else {
val = reflect.ValueOf(tm)
}
fmt.Println(val, tm, reflect.TypeOf(tm))
}
Run Code Online (Sandbox Code Playgroud)
这看起来像编译器中的错误或者可能是已知问题?任何的想法?(我用的是1.11) …