标签: c-preprocessor

如何从C宏的值创建一个char字符串?

例如,如何避免两次写'func_name'?

#ifndef TEST_FUN
#  define TEST_FUN func_name
#  define TEST_FUN_NAME "func_name"
#endif
Run Code Online (Sandbox Code Playgroud)

我想遵循单点真相规则.

C预处理器的版本:

$ cpp --version
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
Run Code Online (Sandbox Code Playgroud)

c dry c-preprocessor

50
推荐指数
2
解决办法
10万
查看次数

字符串化 - 它是如何工作的?

我知道:

#define foo 4  
#define str(s) #s
Run Code Online (Sandbox Code Playgroud)

str(foo)写出:"foo"因为字符串化的第一个文本扩展的执行,但这样的:

 #define xstr(s) str(s)
 #define str(s) #s
 #define foo 4
Run Code Online (Sandbox Code Playgroud)

xstr(foo)写出:"4".

为什么?该过程涉及哪些步骤?

c c++ stringification c-preprocessor

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

为什么在项目中使用#include_next?

引用包装器标题上的iOS 文档:

#include_next不区分<file>和"file"包含,也不检查您指定的文件是否与当前文件同名.它只是查找名为的文件,从找到当前文件的目录后的搜索路径中的目录开始.

使用"#include_next"会导致很大的混乱.我们建议仅在没有其他替代方案时使用.特别是,它不应该用在属于特定程序的标题中; 它应该只用于沿着fixincludes进行全局修正.

那么,有两个问题,#include_next是什么,为什么你需要使用它?

gcc include c-preprocessor

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

是否有用于检测C++ 11x支持的预处理器指令?

如果有一些代码我想尽可能多地使用C++ 11x扩展,但如果不支持则有后备.目前,GCC的OSX版本和VisualC编译器几乎不支持C++ 11x,所以我使用:

#if (defined(__APPLE__) || (defined(_WIN32)))
   ...fallback code without C++11x ...
#else
   ... code using C++11x ...
#endif
Run Code Online (Sandbox Code Playgroud)

这可行,但不是真正正确的事情,特别是因为MacPorts中的gcc编译器支持c ++ 11x.

#define C11X_SUPPORTED型宏吗?也许GCC只有一些东西?

c++ gcc c-preprocessor preprocessor-directive

49
推荐指数
3
解决办法
4万
查看次数

拒绝指针的数组大小的宏

经常教授的标准数组大小的宏是

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
Run Code Online (Sandbox Code Playgroud)

或一些等效的形成.然而,当传入指针时,这种事情会默默地成功,并且在运行时看起来似乎有道理,直到事情神秘地分崩离析.

犯这个错误太容易了:一个具有局部数组变量的函数被重构,将一些数组操作移动到一个以数组作为参数调用的新函数中.

所以,问题是:是否有一个"卫生"宏来检测ARRAYSIZEC中宏的滥用,最好是在编译时?在C++中,我们只使用专门用于数组参数的模板; 在C中,似乎我们需要一些方法来区分数组和指针.(例如,如果我想拒绝数组,我只是(arr=arr, ...)因为数组赋值是非法的).

c arrays macros c-preprocessor

49
推荐指数
4
解决办法
1万
查看次数

如何使C++宏像函数一样?

让我们说由于某种原因你需要写一个宏:MACRO(X,Y). (我们假设您有一个很好的理由不能使用内联函数.) 您希望此宏模拟对没有返回值的函数的调用.


示例1:这应该按预期工作.

if (x > y)
  MACRO(x, y);
do_something();
Run Code Online (Sandbox Code Playgroud)

示例2:这不应导致编译器错误.

if (x > y)
  MACRO(x, y);
else
  MACRO(y - x, x - y);
Run Code Online (Sandbox Code Playgroud)

实施例3:这应该编译.

do_something();
MACRO(x, y)
do_something();
Run Code Online (Sandbox Code Playgroud)

编写宏的天真方式是这样的:

#define MACRO(X,Y)                       \
cout << "1st arg is:" << (X) << endl;    \
cout << "2nd arg is:" << (Y) << endl;    \
cout << "Sum is:" << ((X)+(Y)) << endl;
Run Code Online (Sandbox Code Playgroud)

这是一个非常糟糕的解决方案,它失败了所有三个例子,我不应该解释原因.

忽略宏实际上做的事情,这不是重点.


现在,我经常看到编写宏的方法是将它们用大括号括起来,如下所示:

#define MACRO(X,Y)                         \
{                                          \
  cout << "1st arg is:" << …
Run Code Online (Sandbox Code Playgroud)

c++ c-preprocessor

48
推荐指数
6
解决办法
10万
查看次数

为什么C#中没有宏?

在第一次学习C#时,我很惊讶他们不支持与C/C++相同容量的宏.我意识到#define关键字存在于C#中,但与我在C/C++中的喜爱相比,它非常缺乏.有谁知道为什么C#中缺少真正的宏?

如果这个问题已经以某种形式提出,我很抱歉 - 我保证在发布前花了5分钟时间寻找重复的问题.

.net c# macros c-preprocessor

48
推荐指数
5
解决办法
3万
查看次数

MSVC不会正确扩展__VA_ARGS__

考虑以下代码:

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) F(__VA_ARGS__)
F(1, 2, 3)
G(1, 2, 3)
Run Code Online (Sandbox Code Playgroud)

X = 1 and VA_ARGS = 2, 3两个宏的预期输出,这就是我用GCC得到的,但是,MSVC将其扩展为:

X = 1 and VA_ARGS = 2, 3
X = 1, 2, 3 and VA_ARGS =
Run Code Online (Sandbox Code Playgroud)

也就是说,__VA_ARGS__将其扩展为单个参数,而不是分解为多个参数.

有什么方法吗?

visual-c++ c-preprocessor variadic-macros

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

是否有充分的理由始终在C中用括号括起一个定义?

显然,有些时候#defines必须有括号,如下:

#define WIDTH 80+20

int a = WIDTH * 2; // expect a==200 but a==120
Run Code Online (Sandbox Code Playgroud)

所以我总是括号,即使它只是一个数字:

#define WIDTH (100)
Run Code Online (Sandbox Code Playgroud)

C的新人问我为什么这样做,所以我试图找到一个边缘情况,在一个数字上没有括号#define会导致问题,但我想不出一个.

这种情况是否存在?

c parentheses c-preprocessor

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

C++预处理器中R和L有什么特别之处?

我通过Visual Studio 2013预处理器运行以下代码.输出令我惊讶.

hello.cpp的内容:

#define A(j) #j

A(A?)
A(B?)
A(C?)
A(D?)
A(E?)
A(F?)
A(G?)
A(H?)
A(I?)
A(J?)
A(K?)
A(L?)
A(M?)
A(N?)
A(O?)
A(P?)
A(Q?)
A(R?)
A(S?)
A(T?)
A(U?)
A(V?)
A(W?)
A(X?)
A(Y?)
A(Z?)
Run Code Online (Sandbox Code Playgroud)

命令:

cl /P hello.cpp
Run Code Online (Sandbox Code Playgroud)

hello.i包含:

#line 1 "hello.cpp"



"A?"
"B?"
"C?"
"D?"
"E?"
"F?"
"G?"
"H?"
"I?"
"J?"
"K?"
"L"
"M?"
"N?"
"O?"
"P?"
"Q?"
"R"
"S?"
"T?"
"U?"
"V?"
"W?"
"X?"
"Y?"
"Z?"
Run Code Online (Sandbox Code Playgroud)

我试着打电话给A(L?p:q)时碰到了这个,这导致了"Lp:q",这对我不利.

这是正确的,定义明确的C++吗?C++中的L和R有什么特别之处?如果文件具有.c扩展名,则L和R被视为与字母表的其余部分相同.这与C++ 11有关吗?它必须是一个新功能,因为旧版本的MSVS不会以特殊方式使用L和R.

我能做些什么来阻止MSVS 2013以这种特殊方式治疗L和R?

c++ visual-c++ compiler-bug c-preprocessor c++11

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