我有这个struct:
struct Snapshot
{
double x;
int y;
};
Run Code Online (Sandbox Code Playgroud)
我希望x并且y为0.默认情况下它们是0还是我必须这样做:
Snapshot s = {0,0};
Run Code Online (Sandbox Code Playgroud)
将结构归零的其他方法是什么?
我正在尝试找到一种方便的方法来初始化'pod'C++结构.现在,考虑以下结构:
struct FooBar {
int foo;
float bar;
};
// just to make all examples work in C and C++:
typedef struct FooBar FooBar;
Run Code Online (Sandbox Code Playgroud)
如果我想在C(!)中方便地初始化它,我可以简单地写:
/* A */ FooBar fb = { .foo = 12, .bar = 3.4 }; // illegal C++, legal C
Run Code Online (Sandbox Code Playgroud)
请注意,我想明确地避免使用以下表示法,因为如果我将来更改结构中的任何内容,它会让我感到沮丧:
/* B */ FooBar fb = { 12, 3.4 }; // legal C++, legal C, bad style?
Run Code Online (Sandbox Code Playgroud)
为了实现与/* A */示例中相同(或至少类似)的C++ ,我将不得不实现一个愚蠢的构造函数:
FooBar::FooBar(int foo, float bar) : foo(foo), bar(bar) {}
// -> …Run Code Online (Sandbox Code Playgroud) 考虑:
struct Person
{
int height;
int weight;
int age;
};
int main()
{
Person p { .age = 18 };
}
Run Code Online (Sandbox Code Playgroud)
上面的代码在C99中是合法的,但在C++ 11中不合法.
什么是C++ 11标准委员会排除了这样一个方便的功能支持的理由?
昨天我发现了一些结构初始化代码,它让我循环.这是一个例子:
typedef struct { int first; int second; } TEST_STRUCT;
void testFunc() {
TEST_STRUCT test = {
second: 2,
first: 1
};
printf("test.first=%d test.second=%d\n", test.first, test.second);
}
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是(对我来说),这是输出:
-> testFunc
test.first=1 test.second=2
Run Code Online (Sandbox Code Playgroud)
如您所见,struct正确初始化.我不知道标签语句可以这样使用.我已经看到了其他几种进行结构初始化的方法,但我没有在任何在线C FAQ上找到任何这种结构初始化的例子.有人知道这是如何/为什么有效?
我对c ++ 20功能之一(指定的初始化程序)有疑问(有关此功能的更多信息,请点击此处)
#include <iostream>
constexpr unsigned DEFAULT_SALARY {10000};
struct Person
{
std::string name{};
std::string surname{};
unsigned age{};
};
struct Employee : Person
{
unsigned salary{DEFAULT_SALARY};
};
int main()
{
std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed
std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed
Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok
Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ?
// For e2 compiler prints a warning "missing initializer …Run Code Online (Sandbox Code Playgroud) 在C++ 11中有这样的结构:
struct von
{
std::string Name;
unsigned int ID;
std::vector<std::string> Checks;
};
Run Code Online (Sandbox Code Playgroud)
它应该像这样初始化:
von v = {"",0,{}};
Run Code Online (Sandbox Code Playgroud)
或者像这样:
von v = {};
Run Code Online (Sandbox Code Playgroud)
两种方式似乎都有效,但编译器在后一个示例中警告-Wmissing-field-initializers.
编辑:这是我的编译器选项:g ++ main.cpp -ansi -Wall -Wextra -Weffc ++ -std = c ++ 0x.我正在使用g ++(Debian 4.6.2-12)4.6.2
我搜索了stackoverflow的答案,但我无法得到相关的东西.
我正在尝试通过指定其标记来初始化具有初始值的静态结构实例,但是在编译时遇到错误:
src/version.cpp:10: error: expected primary-expression before ‘.’ token
这是代码:
// h
typedef struct
{
int lots_of_ints;
/* ... lots of other members */
const char *build_date;
const char *build_version;
} infos;
Run Code Online (Sandbox Code Playgroud)
而错误的代码:
// C
static const char *version_date = VERSION_DATE;
static const char *version_rev = VERSION_REVISION;
static const infos s_infos =
{
.build_date = version_date, // why is this wrong? it works in C!
.build_version = version_rev
};
const infos *get_info()
{
return &s_infos;
}
Run Code Online (Sandbox Code Playgroud)
所以基本的想法是绕过"其他成员"的初始化,只设置相关build_date和build_version …
对于我正在研究的微控制器项目,我正在编写一个共享库.我正在混合C和C++,主要是因为需要在低级部分完成所有指针算术,因为我的代码很容易映射到C库.但是,在不同的微控制器上,我想将C++用于硬件部分.作为HAL,我使用函数指针的结构来给出实现.
现在,指针在公共文件中声明,如下所示:
extern HALPointer * _hal_ptr;
Run Code Online (Sandbox Code Playgroud)
现在,在我的C文件中,我只是说
HALPointer _hal_ptr = (HALPointer) {
.init = &Native_init,
.destroy = &Native_destroy,
.write = &Native_write,
...
}
Run Code Online (Sandbox Code Playgroud)
但是,在我的C++文件中,我无法使用命名的初始化列表.我正在使用G ++支持c ++ 98,gnu ++ 98,c ++ 0x和gnu ++ 0x.有没有办法做到这一点?
编辑:这是在C++文件中完成的,使用C调用约定等.
extern "C" {
}
Run Code Online (Sandbox Code Playgroud)
也不可能使用函数来执行此操作.此外,元素的顺序可能会改变,因此需要命名成员初始化.
编辑2:在C++结构初始化中,提出了一些解决方案,遗憾的是,这些解决方案不起作用或不合适.由于元素的顺序必然会发生变化(并且可能会添加项目等),因此非命名版本不是一个选项.最后一个解决方案无法编译.另一种解决方案至少可以说是可怕的.
编辑3:坚持可怕的解决方案:
extern "C" {
HALPointer _hal_ptr = (_hal_tr = HALPointer(),
_hal_ptr.init = &PRU_init,
_hal_ptr.destroy = &PRU_destroy,
....
_hal_ptr);
}
Run Code Online (Sandbox Code Playgroud) 我遇到了C89之后似乎没有通过任何C标准解决的问题,除非提到结构初始化限制已被解除.但是,我使用Open Watcom IDE(用于调试)遇到错误,其中编译器声明初始化程序必须是常量表达式.
这是正在发生的事情的要点.
typedef struct{
short x;
short y;
} POINT;
void foo( short x, short y )
{
POINT here = { x, y }; /* <-- This is generating the error for the compiler */
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
任何想法为什么,或什么标准不允许?
#include <iostream>
using namespace std;
struct A {
// Some Other Code
int x;
};
A a1;
int main(){
A a2;
cout << "a1.x = " << a1.x << endl;
cout << "a2.x = " << a2.x << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++14 标准 (ISO/IEC 14882:2014) 第 8.5 节,第 12 段:
如果没有为对象指定初始化程序,则该对象是默认初始化的。当获得具有自动或动态存储期限的对象的存储时,该对象具有不确定值,如果没有对该对象执行初始化,则该对象保留一个不确定值,直到该值被替换(5.17)。[注意:具有静态或线程存储持续时间的对象是零初始化的,参见 3.6.2。- 尾注]
那么a1有静态存储持续时间和a2自动存储持续时间吗?的定义Struct A在全局命名空间以及a1声明中,而a2声明在块范围内(在main()函数内部)。
此外,第 3.6.2 节说:
第 1 段:
作为程序启动的结果,具有静态存储持续时间的非局部变量被初始化。
第 2 段: …
我正在尝试将嵌入式目标的一些遗留 C 代码迁移到 C++ 以解决兼容性问题,并且我在 C++ 中遇到了一些联合问题。
在我们的项目中,我们采用以下联合样式来减少 RAM 使用量:
typedef union unionTest
{
struct
{ uint32_t nField1:5
; uint32_t nField2:4
; uint32_t nField3:23
;}
; uint32_t nRaw ///< Raw data
;} unionTest;
// A global variable for configuration
unionTest myCUnion = {.nField1 = 1, .nField2 = 2, .nField3 = 3 };
Run Code Online (Sandbox Code Playgroud)
这很有效,易于使用,并且编译器在编译时以正确的值初始化位字段
然后在转换为 C++ 时
typedef union unionTest
{
struct
{ uint32_t nField1:5
; uint32_t nField2:4
; uint32_t nField3:23
;}
; uint32_t nRaw ///< Raw data
;} unionTest;
// …Run Code Online (Sandbox Code Playgroud)