相关疑难解决方法(0)

宏中的#和##

  #include <stdio.h>
  #define f(a,b) a##b
  #define g(a)   #a
  #define h(a) g(a)

  int main()
  {
    printf("%s\n",h(f(1,2)));
    printf("%s\n",g(f(1,2)));
    return 0;
  }
Run Code Online (Sandbox Code Playgroud)

只需通过查看程序,"可能"期望输出,对于两个printf语句都是相同的.但是在运行程序时,你得到它:

bash$ ./a.out
12
f(1,2)
bash$
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

c stringification c-preprocessor

29
推荐指数
3
解决办法
2万
查看次数

在C和C++中实现字符串文字串联

AFAIK,这个问题同样适用于C和C++

C标准中规定的"翻译阶段"的第6步(C99标准草案中的5.1.1.2)规定,必须将相邻的字符串文字连接成单个文字.

printf("helloworld.c" ": %d: Hello "
       "world\n", 10);
Run Code Online (Sandbox Code Playgroud)

等同于(语法上):

printf("helloworld.c: %d: Hello world\n", 10);
Run Code Online (Sandbox Code Playgroud)

但是,标准似乎没有指定编译器的哪个部分必须处理它 - 它应该是预处理器(cpp)还是编译器本身.一些在线研究告诉我,这个函数通常应该由预处理器(源#1,源#2,还有更多)执行,这是有道理的.

但是,cpp在Linux中运行显示cpp不执行此操作:

eliben@eliben-desktop:~/test$ cat cpptest.c 
int a = 5;

"string 1" "string 2"
"string 3"

eliben@eliben-desktop:~/test$ cpp cpptest.c 
# 1 "cpptest.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "cpptest.c"
int a = 5;

"string 1" "string 2"
"string 3"
Run Code Online (Sandbox Code Playgroud)

所以,我的问题是:在预处理器或编译器本身中,应该在何处处理该语言的这一特性?

也许没有一个好的答案.基于经验,已知编译器和一般良好工程实践的启发式答案将不胜感激.


PS如果你想知道为什么我关心这个......我正在试图弄清楚我的基于Python的C语法分析器是否应该处理字符串文字连接(目前它没有这样做),或者将它留给cpp哪个它假设在它之前运行.

c c++ string-literals c-preprocessor

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

如何编写带有不同数量的信息参数的c ++断言宏?

我正在尝试编写dbgassert类似于标准的宏assert。除了做什么以外assert,我还想dbgassert打印任意数量的其他参数(包含调试信息)。

下面列出了我到目前为止所拥有的,这是从SO答案改编而来的。但是我在代码中存在可变参数模板或宏的问题。如果我至少使用一个附加参数(“确定”行),则dbgassert可以按预期工作。但是,如果我不给出其他参数,则编译将失败(问题行)。

我在可变参数模板编程方面有一些经验(例如如何打印元组),但是我以前从未使用过可变参数宏。

能否请您解释编写这种可变参数宏组合的正确方法是什么?

顺便说一句,有人可以解释 #EX在宏中魔术吗?它显示了表达式并在gcc4.8.1上为我工作。它得到普遍支持吗?

谢谢,


码:

//corrected reserved identifier issue and assumption issues per comments
#include <cassert>
#include <iostream>
using namespace std;

template <typename ...Args>
void realdbgassert(const char *msg, const char *file, int line, Args ... args) {
  cout << "Assertion failed! \nFile " << file << ", Line " << line << endl 
       << "  Expression: " << msg << endl;
  std::abort();
}

#define …
Run Code Online (Sandbox Code Playgroud)

c++ assert variadic-templates variadic-macros c++11

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

C 中的 # 和 ## 宏

方案一:

#include <stdio.h>
#define foo(x, y) #x #y

int main()
{
  printf("%s\n", foo(k, l)); //prints kl
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

方案2:

#include <stdio.h>
#define foo(m, n) m ## n

int main()
{
  printf("%s\n", foo(k, l)); //compiler error
}
Run Code Online (Sandbox Code Playgroud)

为什么两个程序的输出会有如此大的差异?这两个程序之间的确切区别是什么?

c macros

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