在K&R第6章中,声明如下:
struct{
int len;
char *str;
} *p;
Run Code Online (Sandbox Code Playgroud)
我无法理解这个指针p指向哪个结构,如果这样的指针定义甚至是有效的,因为在书中给出的所有其他示例和我看到的其他示例中,在定义指向结构的指针时,名称需要提及结构,即定义的类型.例如,
struct example{
int a;
...
}s1;
Run Code Online (Sandbox Code Playgroud)
然后,
struct example *ptr = &s1;
Run Code Online (Sandbox Code Playgroud)
所以,提到ptr指向一个类型结构示例而不仅仅是struct.
此外,特别感兴趣的是:
*p-> str获取任何str点;*p-> str ++在访问它指向的任何内容后递增str(就像*s ++);
我无法首先遵循p是什么,因此,也不是增量和解除引用.
这里发生了什么?
提前致谢!
PS我是新来的,所以对这个问题的格式的任何反馈也将不胜感激.
下面的示例代码在Visual C++中编译得很好:
class Test {
private:
struct {
struct {
int privateData;
};
};
};
int main(int, char **)
{
Test test;
test.privateData = 0;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但为什么?我期望编译器错误,因为privateData函数main应该无法访问该成员,因为它应该private像它的容器容器一样.我知道无名结构不是官方C++的一部分,但这个设计是asinine.
顺便说一句,我也试图改变private成protected和struct成union:它看起来像编译器拒绝兑付匿名结构和联合嵌套在另一个匿名结构或联合内部的访问修饰符.
有人可以解释这个功能吗?
结构中的匿名结构中的Brace-or-equal-initializers不会对VS2013生成的输出执行任何操作.有代码:
#include <iostream>
#include <cstdint>
struct S
{
struct
{
uint64_t val = 0;
}anon;
};
int main()
{
S s;
S *a = new S;
std::cout << s.anon.val << std::endl;
std::cout << a->anon.val << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在Linux上使用此命令编译:
g++ -std=c++11 def-init-anon-atruct.cpp -o def-init-anon-atruct
Run Code Online (Sandbox Code Playgroud)
(添加优化标志不会影响结果)
预期结果:
0
0
Run Code Online (Sandbox Code Playgroud)
奇怪的.使用VS2013运行它会产生垃圾值.在实施C++ 11标准方面,谁在这方面是正确的?我非常怀疑这是海湾合作委员会的错.
是否与一些无用的VS编译器选项有关?Windows扩展?由于MS制造的错误,我必须为结构制作默认构造函数?这很荒谬.
member-initialization c++11 anonymous-struct visual-c++-2013
我使用以下联合来简化字节,半字节和位操作:
union Byte
{
struct {
unsigned int bit_0: 1;
unsigned int bit_1: 1;
unsigned int bit_2: 1;
unsigned int bit_3: 1;
unsigned int bit_4: 1;
unsigned int bit_5: 1;
unsigned int bit_6: 1;
unsigned int bit_7: 1;
};
struct {
unsigned int nibble_0: 4;
unsigned int nibble_1: 4;
};
unsigned char byte;
};
Run Code Online (Sandbox Code Playgroud)
它工作得很好,但它也会生成此警告:
警告:ISO C++禁止匿名结构[-pedantic]
好的,很高兴知道.但是......如何从我的g ++输出中得到这个警告?是否有可能在没有这个问题的情况下写出这样的联盟?
我的代码无法使用Visual Studio 2015 Community Edition进行编译,但出现以下错误:
致命错误C1002:编译器在第2遍中没有堆空间
struct Int { int i; };
struct B {
union {
struct { int x; };
struct { Int y; };
};
constexpr B() : x(1) {}
};
struct A { static B b; };
B A::b;
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是最简单的我已经能够通过反复试验归结失败状态,但仍有相当多的事情发生.
让我目瞪口呆的是,以下每一项变化都会导致编译得很好......
constexpr从B构造函数中删除它使它工作:
struct Int { int i; };
struct B {
union {
struct { int x; };
struct { Int y; };
};
B() : …Run Code Online (Sandbox Code Playgroud) 我们有一个庞大的旧C++应用程序,其中包含许多遗留代码和一些用C编写的外部库.这些库很少更新 - 只有当我们发现错误并且供应商提供补丁时.这发生在上周有一个库,在集成新版本后,我们发现如果我们不在本地修改库(我们显然使用上一版本),我们的构建就会出现以下错误消息:
non-local function ‘static E* MyCls::myFct(<anonymous struct>*)’ uses anonymous type
Run Code Online (Sandbox Code Playgroud)
这是因为库声明了许多句柄类型,如下所示:
#define _Opaque struct {unsigned long x;} *
typedef _Opaque Handle;
typedef _Opaque Request;
Run Code Online (Sandbox Code Playgroud)
我们在一些类的函数签名中使用它们:
class MyCls {
public:
static void* myFct(Handle handle);
...
}
Run Code Online (Sandbox Code Playgroud)
这会产生上述错误,因为编译器无法为函数创建正确的名称标记名称,因为_Opaque结构没有名称.
我们当前的解决方法是修补库头文件,显式给结构命名:
//#define _Opaque struct {unsigned long x;} * //Replaced by typedef below!
typedef struct __Opaque {unsigned long x;} * _Opaque;
Run Code Online (Sandbox Code Playgroud)
这显然很糟糕,因为如果可能的话我们不想触摸库.另一个更糟糕的选择是将类型转换为void*所有函数签名并将它们转换回各自的类型.并且在纯C中重写每个受影响的函数是最糟糕的选择...
所以,我的问题是:有没有比修补图书馆更好的选择?我有一个简单的解决方案吗?解决这个问题的最佳方法是什么?
我正在调查C11草案,它说
没有标记的结构类型的未命名成员称为匿名结构; 没有标记的联合类型的未命名成员称为匿名联合.匿名结构或联合的成员被视为包含结构或联合的成员.
所以我构建了以下测试用例
// struct type with no tag
typedef struct {
unsigned char a;
unsigned char b;
// ... Some other members ...
unsigned char w;
} AToW;
union
{
AToW; // <- unnamed member
unsigned char bytes[sizeof(AToW)];
} myUnion;
Run Code Online (Sandbox Code Playgroud)
Clang和GCC都抱怨这位未透露姓名的成员,并说该声明没有效果.我做错了什么,还是他们根本不支持这个功能呢?
C标准规定:
指向结构对象的指针(适当地强制转换)指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然.
如果所讨论的结构的第一个成员是匿名结构/联合,是否有任何可能的(和明确定义的)方法在C11中执行这样的"合适的强制转换"?或者,如果包含结构是匿名的,则执行"反之亦然"向后转换?
我想,使用与匿名结构相同的成员序列转换为非匿名结构将使得它不能很好地定义,因为它们不兼容,因此,不能保证具有相同的内存布局.
但是,C标准规定:
此外,如果它们的标记和成员满足以下要求,则在单独的转换单元中声明的两个结构,联合或枚举类型是兼容的:如果使用标记声明一个,则另一个应使用相同的标记声明.如果两者都在各自的翻译单元内的任何地方完成,则以下附加要求适用:其成员之间应存在一对一的对应关系<...>
我们可以尝试将此规则应用于匿名结构吗?比如说,如果我们有以下设置:
header.h:
struct container {
struct {
int a;
char b;
};
};
void print(struct container *pcontainer);
Run Code Online (Sandbox Code Playgroud)
sep.c:
#include <stdio.h>
#include "header.h"
void print(struct container *pcontainer){
printf("%d\n", ((struct { int a; char b; }*)pcontainer)->a);
}
Run Code Online (Sandbox Code Playgroud)
main.c中:
#include "header.h"
int main(void){
struct container container, *pcontainer;
pcontainer = &container;
pcontainer->a = 1;
print(pcontainer);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
(这在gcc(GCC)4.8.3 20140911上编译,输出1).
考虑在内的铸造中使用的匿名结构print功能和所述匿名结构是的第一构件struct container ,在卷起main.c.它们可以被视为"在单独的翻译单元中声明的类型"吗?此外,他们真的满足所有其他兼容性要求,还是我误解了什么?
我注意到有几种方法可以在C中的其他结构中定义结构:
struct s {
int abc;
struct {
int a;
};
struct {
int b;
} intern;
struct i {
int c;
};
struct i2 {
int d;
} intern2;
struct i3 {
int e;
};
struct i3 intern3;
};
Run Code Online (Sandbox Code Playgroud)
这个结构使用gcc或g ++编译很好,所以我假设所有参数都可以通过某种方式访问.我试过这样的:
int main(int argc, char const *argv[])
{
struct s mystruct;
mystruct.abc = 0;
mystruct.a = 1;
mystruct.intern.b = 2;
mystruct.c = 3; // <-- does not compile
mystruct.intern2.d = 4;
mystruct.intern3.e = 5;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
除了访问mystruct.c …
我们可以在循环struct内声明匿名,如下所示(g++):for
for(struct { bool OK = true; } s; s.OK; s.OK = false)
std::cout << "Hello, world!\n";
Run Code Online (Sandbox Code Playgroud)
但是,此代码会在MSVC中导致编译错误,如下所示:
source_file.cpp(7):错误 C2332:“struct”:缺少标记名称
source_file.cpp(7):错误 C2062:类型“bool”意外
source_file.cpp(7):错误 C4430:缺少类型说明符 - 假定为 int。
注意:C++ 不支持default-int
如何修复它?
版本:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>cl
Microsoft (R) C/C++ 优化编译器版本19.14.26430,适用于 x86
版权所有 (C) Microsoft Corporation。版权所有。
考虑到可以创建这样的匿名结构:
#include <iostream>
struct {
int a;
int b;
} my_anonymous_struct = { 2,3 };
int main() {
std::cout << my_anonymous_struct.a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,是什么原因导致错误出现呢?
#include <iostream>
struct file {
int min;
int max;
};
auto read_historic_file_dates(file F) -> struct { int min; int max; } {
return { F.min, F.max };
}
int main() {
file F = { 1, 4 };
auto [min_date, max_date] = read_historic_file_dates(F);
}
Run Code Online (Sandbox Code Playgroud)
错误:
<source>:8:42: error: declaration of anonymous struct must be a definition …Run Code Online (Sandbox Code Playgroud)