Mik*_*wan 10 c macros c-preprocessor
如何创建C宏来获取字符串的整数值?具体的用例来自这里的一个问题.我想改变这样的代码:
enum insn {
sysenter = (uint64_t)'r' << 56 | (uint64_t)'e' << 48 |
(uint64_t)'t' << 40 | (uint64_t)'n' << 32 |
(uint64_t)'e' << 24 | (uint64_t)'s' << 16 |
(uint64_t)'y' << 8 | (uint64_t)'s',
mov = (uint64_t)'v' << 16 | (uint64_t)'o' << 8 |
(uint64_t)'m'
};
Run Code Online (Sandbox Code Playgroud)
对此:
enum insn {
sysenter = INSN_TO_ENUM("sysenter"),
mov = INSN_TO_ENUM("mov")
};
Run Code Online (Sandbox Code Playgroud)
在哪里INSN_TO_ENUM扩展到相同的代码.性能将是相同的,但可读性将大大提高.
我怀疑在这种形式下它可能是不可能的,因为C预处理器无法进行字符串处理,所以这也是一个不可取但可接受的解决方案(变量参数宏):
enum insn {
sysenter = INSN_TO_ENUM('s','y','s','e','n','t','e','r'),
mov = INSN_TO_ENUM('m','o','v')
};
Run Code Online (Sandbox Code Playgroud)
这是一个编译时的纯C解决方案,您指出可以接受。您可能需要将其扩展为更长的助记符。我将继续考虑所需的那个(即INSN_TO_ENUM("sysenter"))。有趣的问题:)
#include <stdio.h>
#define head(h, t...) h
#define tail(h, t...) t
#define A(n, c...) (((long long) (head(c))) << (n)) | B(n + 8, tail(c))
#define B(n, c...) (((long long) (head(c))) << (n)) | C(n + 8, tail(c))
#define C(n, c...) (((long long) (head(c))) << (n)) | D(n + 8, tail(c))
#define D(n, c...) (((long long) (head(c))) << (n)) | E(n + 8, tail(c))
#define E(n, c...) (((long long) (head(c))) << (n)) | F(n + 8, tail(c))
#define F(n, c...) (((long long) (head(c))) << (n)) | G(n + 8, tail(c))
#define G(n, c...) (((long long) (head(c))) << (n)) | H(n + 8, tail(c))
#define H(n, c...) (((long long) (head(c))) << (n)) /* extend here */
#define INSN_TO_ENUM(c...) A(0, c, 0, 0, 0, 0, 0, 0, 0)
enum insn {
sysenter = INSN_TO_ENUM('s','y','s','e','n','t','e','r'),
mov = INSN_TO_ENUM('m','o','v')
};
int main()
{
printf("sysenter = %llx\nmov = %x\n", sysenter, mov);
return 0;
}
Run Code Online (Sandbox Code Playgroud)