让我们假设我们有一个结构,用于保存3个带有一些成员函数的双精度数:
struct Vector {
double x, y, z;
// ...
Vector &negate() {
x = -x; y = -y; z = -z;
return *this;
}
Vector &normalize() {
double s = 1./sqrt(x*x+y*y+z*z);
x *= s; y *= s; z *= s;
return *this;
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
这有点简单,但我相信你同意类似的代码.这些方法可以方便地链接,例如:
Vector v = ...;
v.normalize().negate();
Run Code Online (Sandbox Code Playgroud)
甚至:
Vector v = Vector{1., 2., 3.}.normalize().negate();
Run Code Online (Sandbox Code Playgroud)
现在,如果我们提供了begin()和end()函数,我们可以在new-style for循环中使用Vector,比如循环遍历3个坐标x,y和z(你无疑可以构造更多"有用"的例子通过用例如String替换Vector):
Vector v = ...;
for (double x : v) { ... }
Run Code Online (Sandbox Code Playgroud)
我们甚至可以这样做:
Vector v = ...;
for …Run Code Online (Sandbox Code Playgroud) 我希望C类有一个类型为C的静态constexpr成员.这在C++ 11中是否可行?
尝试1:
struct Foo {
constexpr Foo() {}
static constexpr Foo f = Foo();
};
constexpr Foo Foo::f;
Run Code Online (Sandbox Code Playgroud)
g ++ 4.7.0说:'无效使用不完整类型'指的是Foo()调用.
尝试2:
struct Foo {
constexpr Foo() {}
static constexpr Foo f;
};
constexpr Foo Foo::f = Foo();
Run Code Online (Sandbox Code Playgroud)
现在的问题是在类定义中缺少constexpr成员的初始化器f.
尝试3:
struct Foo {
constexpr Foo() {}
static const Foo f;
};
constexpr Foo Foo::f = Foo();
Run Code Online (Sandbox Code Playgroud)
现在g ++抱怨重新声明Foo::f不同的内容constexpr.
在C11中工作,结构如下:
struct S {
unsigned a : 4;
_Bool b : 1;
};
Run Code Online (Sandbox Code Playgroud)
由GCC布局为unsigned(4字节),其中使用4位,然后是_Bool(4字节),其中使用1位,总大小为8字节.
注意,C99和C11特别允许_Bool作为位字段成员.C11标准(也可能是C99)也在§6.7.2.1"结构和联合说明符"中声明:
实现可以分配任何足够大的可寻址存储单元来保存位字段.如果剩余足够的空间,则紧跟在结构中的另一个位字段之后的位字段将被打包到相同单元的相邻位中.
所以我认为b上面的成员应该被打包到为成员分配的存储单元中a,从而产生一个总大小为4字节的结构.
GCC正确的行为和包装不使用相同类型的两个成员发生时,或者当一个unsigned和其他signed,但类型unsigned和_Bool似乎是由海湾合作委员会被认为过于鲜明它正确地处理它们.
有人可以证实我对标准的解释,这确实是一个GCC错误吗?
我也对一种解决方法感兴趣(一些编译器开关,pragma,__attribute__......).
我正在使用gcc 4.7.0 -std=c11(尽管其他设置显示相同的行为.)
可以依赖外部I/O作为跨线程同步的一种形式吗?
具体来说,请考虑下面的伪代码,假设存在网络/套接字函数:
int a; // Globally accessible data.
socket s1, s2; // Platform-specific.
int main() {
// Set up + connect two sockets to (the same) remote machine.
s1 = ...;
s2 = ...;
std::thread t1{thread1}, t2{thread2};
t1.join();
t2.join();
}
void thread1() {
a = 42;
send(s1, "foo");
}
void thread2() {
recv(s2); // Blocking receive (error handling omitted).
f(a); // Use a, should be 42.
}
Run Code Online (Sandbox Code Playgroud)
我们假设远程机器只发送数据,s2在接收到"foo"从s1.如果这个假设失败,那么肯定会产生未定义的行为.但如果它成立(并且没有其他外部故障发生,如网络数据损坏等),该程序是否会产生定义的行为?
"从不","未指定(取决于实现)","取决于send/recv实现提供的保证"是我期望的那种示例答案,最好是C++标准(或其他相关标准)的理由,例如POSIX for socket/networking).
如果"从不",则更a改为 …
c++ ×3
c++11 ×2
bit-fields ×1
c11 ×1
c99 ×1
compiler-bug ×1
constexpr ×1
for-loop ×1
foreach ×1
gcc ×1
memory-model ×1
sockets ×1