考虑这个C代码:
extern volatile int hardware_reg;
void f(const void *src, size_t len)
{
void *dst = <something>;
hardware_reg = 1;
memcpy(dst, src, len);
hardware_reg = 0;
}
Run Code Online (Sandbox Code Playgroud)
该memcpy()呼叫必须在两个任务之间发生.通常,由于编译器可能不知道被调用函数将执行什么操作,因此它无法将对函数的调用重新排序为在赋值之前或之后.但是,在这种情况下,编译器知道函数将执行什么操作(甚至可以插入内联内置替换),并且它可以推断出memcpy()永远不能访问的内容hardware_reg.在我看来,编译器在移动memcpy()调用时会遇到麻烦,如果它想这样做的话.
所以,问题是:单独的函数调用是否足以发出阻止重新排序的内存屏障,或者在这种情况下,在调用之前和之后需要显式内存屏障memcpy()?
如果我误解了事情,请纠正我.
我想重载operator<<任意数组,以便代码cout << my_arr可以工作.首先,我尝试重载operator<<on 的第二个参数const T (&arr)[N],其中T和N是模板参数.但是测试代码会发现副作用:const char[]也匹配类型规范,新的重载与流类中定义的重载冲突.示例代码:
#include <cstddef>
#include <iostream>
template<typename T, std::size_t N>
std::ostream& operator<<(std::ostream& os, const T (&arr)[N])
{
/* do stuff */
return os;
}
int main()
{
std::cout << "noooo\n"; /* Fails: ambiguous overload */
}
Run Code Online (Sandbox Code Playgroud)
这样的阵列打印操作员是否仍然可以实现?
为什么会这样?该代码在Linux上运行GCC 4.7,在Windows上运行MSVC++ 2010时不会生成警告.然而,在ideone.com上,它崩溃了SIGILL.这里涉及到未定义的行为吗?
#include <iostream>
#include <cstdarg>
using namespace std;
enum types
{
INT,
DOUBLE,
CHAR,
STRING
};
struct mt
{
types type;
union
{
int i;
double d;
char c;
const char *s;
} val;
mt(int i)
: type(INT)
{
val.i = i;
}
mt(double d)
: type(DOUBLE)
{
val.d = d;
}
mt(char c)
: type(CHAR)
{
val.c = c;
}
mt(const char *s)
: type(STRING)
{
val.s = s;
}
};
void print(int …Run Code Online (Sandbox Code Playgroud)