我正在尝试创建一种安全缓冲区,可自动处理没有任何分支的溢出。缓冲区大小是2的幂,并且只应具有有效的正(即不包括零)索引。它还允许检查删除,如果存储在该索引处的元素等于搜索键,则在给定索引处删除该删除。无分支溢出处理
我基本上去为这样的事情
Element *buffer[256];
inline void buffer_insert(size_t index, Element *elem){
buffer[index < 256 && index] = elem;
}
//Optional: checked insert to prevent overwrite. Will only insert
//if the buffer holds NULL at index.
inline void buffer_checkedInsert(size_t index, Element * elem){
buffer[index && !buffer[index < 256 && index]] = elem;
}
inline void buffer_checkedRemove(size_t index, Element *elem){
buffer[0] = NULL; //Maybe useful if buffer[0] stores elem
buffer[((elem == buffer[index < 256 && index)) && index] = NULL;
}
所以我基本上要访问索引0时传入的索引超出范围,如buffer[0]
不是一个有效的缓冲指数。我也想访问索引0,只要要移除的元素不等于传入移除的元素,并且我可能还想访问索引0(如果缓冲区包含索引处的内容)。
我的问题是:
- 是我真正的网点?因为如果C编译器决定使用& &上的短路,则代码可能会分支。
- 如果& &会导致分支,有没有替代方案在这种情况下具有相同的行为,不涉及分支?
- 这可以比基本的溢出检查更快吗?或者C编译器能以某种方式给出
if(index < 256) buffer[index] = elem
的无分支版本?
'&&'按设计短路。它的使用通常会发出一个分支。使用比较运算符的结果作为值也可能导致分支被发射,具体取决于体系结构(在x86上它不)。 – fuz
作为一个概念性问题:想一想,如果超越边界的读取和写入默默无闻,而不是像他们应该崩溃一样真的会更好。另外认为如果无分代码真的值得额外的长度。几乎从不会很便宜,我认为你不会偶尔触发溢出检查。 – fuz
'&&'不会做你认为它做的事。例如'&&'的结果只能是'0'或'1'。 – Hurkyl