小编Ale*_*lex的帖子

ANSI C中的变量宏替代方案

我知道在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)

c c89 variadic-macros

7
推荐指数
2
解决办法
1900
查看次数

短变量声明和"变量声明和未使用"错误

我遇到了一个奇怪的问题,下面的代码无法编译:

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) …

go

1
推荐指数
1
解决办法
322
查看次数

标签 统计

c ×1

c89 ×1

go ×1

variadic-macros ×1