c - 在预处理中计算其评估可能导致副作用的 2 个操作数的最大值
问题描述
我发现自己需要计算 2 个操作数的最大值。
- 这 2 个操作数可能有副作用,必须只计算一次,并且
- 评估发生在预处理宏中,并且不优选分配附加变量(尽管如果可行,则允许)。
到目前为止,我提出的最佳解决方案是将bit-or
它们放在一起,这比算术加法的开销更小。即使这没有得到 2 个操作数的最大值,它也给出了一个足够大的值来容纳任一大小的工作上下文。
typedef struct {
void (*initfunc)(void *restrict x);
void (*updatefunc)(void *restrict x, const void *restrict in, size_t len);
void (*finalfunc)(void *restrict x, void *restrict out);
} hash_funcs_set;
typedef struct {
unsigned hlen_msg;
unsigned hlen_mgf;
hash_funcs_set_t hfuncs_msg, hfuncs_mgf;
} pkcs1_padding_oracles_base_t;
#define PKCS1_PADDING_ORACLES_T(...) \
struct { \
pkcs1_padding_oracles_base_t base; \
uint8_t hashctx[__VA_ARGS__]; \
}
typedef PKCS1_PADDING_ORACLES_T() pkcs1_padding_oracles_t;
#define PKCS1_PADDING_ORACLES_CTX_SIZE_X(hmsg, hmgf) ( \
sizeof(pkcs1_padding_oracles_base_t) + \
(CTX_BYTES(hmsg) | CTX_BYTES(hmgf)) )
// CTX_BYTES is a function-like macro that invokes hmsg (which
// can be either another function-like expression macro, or a
// function pointer), to obtain the size of hash function working
// context size.
// Possible definitions of a hmsg/hmgf:
#define macro_SHA256(q) (\
q==1 ? 32 /* output bytes */ : \
q==2 ? 256 /* size of working variable set */ : \
q==3 ? (intptr_t)SHA256_Init : \
q==4 ? (intptr_t)SHA256_Update : \
q==5 ? (intptr_t)SHA256_Final : \
0)
intptr_t info_SHA256(int q) { return macro_SHA256(q); }
...
#define OUT_BYTES(obj) (obj(1))
#define CTX_BYTES(obj) (obj(2))
...
我认为这是可以接受的原因是因为我实际上是为数据结构联合(因此是整数)分配内存工作上下文,它可能在不同时间由 2 组不同的函数使用而不会发生冲突,我希望可以发现一些 XY 问题并且可以设计出更好的解决方案。
我希望在和是常量PKCS1_PADDING_ORACLES_CTX_SIZE_X(hmsg,hmgf)
表达式时扩展为常量表达式,但它们可以是任何东西并且可能会导致副作用。hmsg
hmgf
语言是标准C,任何版本。编译器特定的功能不是首选。
解决方案
2个操作数有副作用
这意味着它们不是常量表达式。所以只需编写一个函数来计算最大值。使用适当的类型。
// hash_ret_type - the return type of hash function.
// Or it's just unsigned long long or uintmax_t, if super lazy.
hash_ret_type hash_max(hash_ret_type a, hash_ret_type b) {
return a > b ? a : b;
}
#define PKCS1_PADDING_ORACLES_CTX_SIZE_X(hmsg, hmgf) ( \
sizeof(pkcs1_padding_oracles_base_t) + \
hash_max(CTX_BYTES(hmsg), CTX_BYTES(hmgf)) )
如果您对使用 GNU 扩展感兴趣,您可能想对max() linux 内核宏感兴趣。
推荐阅读
- javascript - 如何使用 javascript 遍历 html 表输入
- jasper-reports - Jasper Reports:如何将报表单元动态寻址为子报表的源
- azure - 不支持关键字:天蓝色集成连接的“身份验证”错误
- javascript - 如何将 angular6-json-schema-form 与 NoFramework 模块一起使用?
- javascript - 在 Wordpress 主题模板中排队 jQuery 插件
- css - Bootstrap 4 最大高度 div
- python - 使用 tsfresh 中的 extract_(relevant_) 特征的(铸造)错误
- javascript - How do you push data to a readable stream from within a function?
- java - List with inner List to Map Java Stream Api
- r - Unable to load rJava using Rscript on Ubuntu 18.04