您遇到的最糟糕的 现实世界宏/预处理器滥用是什么(请不要设想IOCCC答案*哈哈*)?
如果它真的很有趣,请添加一个简短的片段或故事.目标是教一些东西,而不是总是告诉人们"永远不要使用宏".
ps:之前我曾经使用过宏...但是当我有一个"真正的"解决方案时,我最终会摆脱它们(即使真正的解决方案是内联的,它也会变得类似于宏).
额外:举一个例子,宏实际上比非宏解决方案更好.
相关问题: C++宏什么时候有用?
对于一些基地.基数1甚至.某种复杂的替代.
此外,当然,在现实生产代码中这样做并不是一个好主意.我只是出于好奇而被问到.
我想编写在编译时评估的预处理器函数/数组.例如,如果我定义
#define MYARR[] {5,4,3,2,1,0}
Run Code Online (Sandbox Code Playgroud)
然后,代码
int x = R[0];
Run Code Online (Sandbox Code Playgroud)
应该表示为
int x = 5;
Run Code Online (Sandbox Code Playgroud)
到编译器.(当然只能在索引中使用文字).如果代码大小/内存很关键且我们不想存储MYARR,这很重要,但我们需要它以方便编码.
编译时间函数也会很好.例如,像
#define MYMAP(n)
#if n==1
5
#else
2
Run Code Online (Sandbox Code Playgroud)
所以,声明
int x = MYMAP(4);
Run Code Online (Sandbox Code Playgroud)
应该作为编译器呈现给编译器
int x = 2;
Run Code Online (Sandbox Code Playgroud)
显然,我们必须使用文字作为参数.这可能吗?
我正在做一些微控制器编程,并且我有以下代码:
#define F_CPU 8000000
#define F_ADC (F_CPU / 64.0)
#define T_ADC (1.0/F_ADC)
Run Code Online (Sandbox Code Playgroud)
有没有办法在编译时打印出 T_ADC 的计算值?我尝试将其字符串化
#define STRINGIFY(s) XSTRINGIFY(s)
#define XSTRINGIFY(s) #s
#pragma message ("T_ADC " STRINGIFY(T_ADC))
Run Code Online (Sandbox Code Playgroud)
但这只是给出了宏展开式“(1/(8000000/64))”,而不是实际值。
printf这是一个微控制器程序,在启动时执行此操作很尴尬。我正在使用 gcc,如果有帮助的话,我很乐意使用任何非标准 gcc 功能。
如何在Windows上使用预处理器执行log(x)?
喜欢:
#define A log(4)/log(2)
Run Code Online (Sandbox Code Playgroud)
在我的代码之后的数组
int b[A]; // A=2 will be computed with the preprocessor ! not in run time
Run Code Online (Sandbox Code Playgroud) 我正在为微控制器编写代码; 由于ATMega128没有硬件乘法器或分频器,因此这些操作必须在软件中完成,并且它们占用相当多的周期.但是,为了代码的可移植性和易用性,我宁愿不将预先计算的值硬编码到我的代码中.例如,我有许多依赖于系统时钟频率的任务.目前我的运行频率为16MHz,但我应该选择降低它,比如降低电池应用的功耗,我想改变一行代码而不是多行代码.
那么说,C预处理器可以计算算术表达式,然后将结果"粘贴"到我的代码中,而不是将原始表达式"粘贴"到代码中吗?如果是这样,我该怎么做呢?他们的编译器选项和我需要考虑的是什么?
注意:我想要计算的值是常量值,所以我没有理由认为这不是一个特征.
c compiler-construction compiler-optimization c-preprocessor
在我的系统上,我有一个/usr/include目录,curl/options.h其中有一个文件,其中包含 CURLOT_FLAG_ALIAS 的预处理器定义。
如果我有以下 test.txt:
#include "curl/options.h"
curlot flag alias is: CURLOT_FLAG_ALIAS
Run Code Online (Sandbox Code Playgroud)
然后我可以这样做来扩展文本文件中的宏:
$ gcc -E -P -x c -I/usr/include test.txt
typedef enum {
CURLOT_LONG,
CURLOT_VALUES,
CURLOT_OFF_T,
CURLOT_OBJECT,
CURLOT_STRING,
CURLOT_SLIST,
CURLOT_CBPTR,
CURLOT_BLOB,
CURLOT_FUNCTION
} curl_easytype;
struct curl_easyoption {
const char *name;
CURLoption id;
curl_easytype type;
unsigned int flags;
};
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_name(const char *name);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_by_id(CURLoption id);
CURL_EXTERN const struct curl_easyoption *
curl_easy_option_next(const struct curl_easyoption *prev);
curlot flag alias …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
1. #define SUFFIX 5-5
2. #define XFUNC_0( x ) (100 * x)
3. #define XFUNC_1( x ) (101 * x)
4. #define XFUNC_2( x ) (102 * x)
5. #define CATX( x, y ) x##y
6. #define CAT( x, y ) CATX( x, y )
7. #define XFUNC CAT( XFUNC_, SUFFIX )
8. #if XFUNC(2) == 200
...... etc
N. #endif
Run Code Online (Sandbox Code Playgroud)
这段代码似乎没有用,这是因为它只是我真实代码的一部分,简化了.问题是: - 如何说服预处理器先执行5-5(只是数学运算的一个例子),并将结果(在本例中为零)连接到XFUNC_?因为它现在不起作用,它告诉我"预处理器指令后面的意外令牌 - 期望换行",在第8行.更新:看来是正确的,上面的代码将是简单的代码替换结果XFUNC_5-5.但在这种情况下,我还有另一个问题: - 确实存在一种方法来获得像宏这样的函数或接受输入(参数)表达并输出数字的东西; 我想也许类似于你放置连续数字的向量:你把索引(这可能是一个完整的表达)你得到的结果是相同的,除了现在不是表达而是"纯"数字然后可以连接