I have look-up-table as defined below and I’m making use of GCC. When I compile I get warnings as
warning: braces around scalar initializer
What does this warning mean? How should I initialize this LUT? Am I making a mistake in initializing this structures?
Help!!
typedef struct TECH
{
float velocity1, velocity2;
float temp;
float measure;
int id;
float storage[64];
}TECH;
struct TECH lut_model_1[2] = {{{296.001465},
{74.216972},
{2.025908},
{1.516384},
{1},
{0.001746,
0.000256, 0.006216, 0.005249, -0.001668, -0.001377, 0.009865, 0.010454, -0.000288, -0.005853, 0.010584, 0.015440, 0.000465, -0.000602, 0.004330, 0.005700, 0.017120,
0.233015, 0.034154, 0.244022, 0.007644, 0.385683, 0.042960, 0.406633, -0.007811, 0.346931, 0.040123, 0.387361, 0.007030, 0.225309, 0.017897, 0.241024, 0.003700,
0.103601, 0.060748, 0.121059, -0.045041, 0.076974, 0.070647, 0.148810, -0.022399, 0.074007, 0.054797, 0.141794, 0.010376, 0.052482, 0.045013, 0.078443, -0.019940,
-0.057353, 0.044285, 0.066622, -0.058232, -0.093817, 0.064753, 0.126611, -0.008286, -0.085634, 0.029582, 0.140443, 0.009189, -0.052974, 0.036057, 0.087536}},
{{309.270569},
{74.520226},
{2.088673},
{1.595730},
{1},
{-0.003261,
0.001452, 0.006673, 0.007092, 0.001020, 0.002904, 0.009037, 0.009587, -0.001494, 0.000296, 0.009327, 0.010013, -0.000301, -0.002727, 0.005875, 0.008888, -0.016850,
0.231185, 0.029758, 0.241629, 0.009411, 0.382748, 0.057553, 0.407984, -0.019496, 0.393691, 0.045355, 0.411033, -0.019787, 0.185746, 0.027101, 0.216863, 0.010189,
0.050463, 0.041380, 0.059462, 0.009747, 0.093188, 0.089831, 0.132579, -0.049612, 0.058789, 0.075130, 0.122026, -0.022185, 0.017041, 0.035450, 0.074255, -0.002068,
-0.061219, 0.040752, 0.087084, -0.013021, -0.106098, 0.066566, 0.140099, -0.041966, -0.073433, 0.055231, 0.125908, -0.003481, -0.050690, 0.017257, 0.085251}}};
-
02-27-2008
#1
Registered User
error: braces around scalar initializer…
The following snippet encompasses lines 4-56 in my code:
Code:
record tmpKnowledgeBase[] = { {"REPETITION T1**"}, LINK_SPECIAL, { "Why are you repeating yourself?", "I heard you the first time.", "This conversation is starting to bore me.", "Don't you have anything else to say?" }, {"REPETITION T2**"}, LINK_SPECIAL, { "Yes, I know. You already said that.", "Didn't you already say that?", "I'm getting the impression you're repeating yourself." }, {"BOT DONT UNDERSTAND**"}, LINK_SPECIAL, { "What are you talking about?.", "I'm not sure I understand what you mean...", "Huh?" }, {"NULL INPUT**"}, LINK_SPECIAL, { "What the heck is that supposed to mean?", "At least take the time to say SOMETHING.", "Talking requires TWO people, you know." }, {"NULL INPUT REPETITION**"}, LINK_SPECIAL, { "...", "Wow, that's really annoying. Stop it.", "What's wrong with you?", "This isn't funny - it's just stupid." }, {"HELLO", "HI"}, LINK_OR, { "Hey there!", "Hello.", "Hiya!" }, {"WHAT", "YOUR", "NAME"}, LINK_AND, { "My name is "+botName+"!", "Does it really matter?", botName+", at your service." } };
Here are the declarations for structs record and keywords:
Code:
typedef struct { std::string keyset[TURNERBOT_MAX_KEYWORDS]; int linkType; } keywords; typedef struct { keywords keys; std::string response[TURNERBOT_MAX_RESP]; } record;
Now, this looks fine to ME, but… I’m not that great a C++. I’m getting the following error when I try to compile:
Code:
/home/shane/TurnerBot/src/bot.cpp: In member function 'void TurnerBot::generateKnowledgeBase()': /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'int' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'int' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'int' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string' /home/shane/TurnerBot/src/bot.cpp:56: error: braces around scalar initializer for type 'std::string'
Can somebody please tell me what this is talking about and how I can fix it? =/
-
02-27-2008
#2
Just Lurking
I think I ran into this once before. Although a single string literal initializer may be optionally enclosed in braces…
Code:
const char text[] = {"initializer"};
…I don’t believe this recurses to members of an aggregate. I believe the fix is to write them as
Code:
const char text[] = "initializer";
[edit]Looks up and sees it’s C++.
Either that or there’s using the string constructor for these values.7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
-
02-27-2008
#3
Cat without Hat
Your brace placement is wrong. The way you have it, the compiler thinks that {«REPETITION T1**»} is the initializer for a complete record struct.
Should be
Code:
record tmpKnowledgeBase[] = { { { {"REPETITION T1**"}, LINK_SPECIAL }, { "Why are you repeating yourself?", "I heard you the first time.", "This conversation is starting to bore me.", "Don't you have anything else to say?" } }, // ...
All the buzzt!
CornedBee«There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code.»
— Flon’s Law
Note: This is a C++ specific issue (not C). All versions since C++11. int a[1]{{0}}; // GCC error - should be warning GCC: error: braces around scalar initializer for type 'int' Clang: warning: braces around scalar initializer [-Wbraced-scalar-init] Intel: warning #1119: extra braces are nonstandard MSVC: no warning (with Wall) "I'm frankly stunned that GCC rejects." Quote from a Clang dev (cfe-dev thread linked below). Same error on initializing a scalar member of an aggregate: struct S { int i; }; S s{{0}}; // GCC error - should be warning Or, on initializing an array-of-scalar aggregate member: struct SA { int n[1]; }; SA sa{{{0}}}; // GCC error - should be warning A different but related bug (non-SFINAE-error) was just fixed on Clang trunk. The discussion thread is here: http://clang-developers.42468.n3.nabble.com/braces-around-scalar-initializer-warning-should-be-error-td4063311.html The Clang fix commit is here, with test code applicable to this GCC bug: https://github.com/llvm-mirror/clang/commit/3410781dffff51e89751a2494bd8dfe7e7d83541 Here's a compiler explorer link with the test code: https://gcc.godbolt.org/z/8HCba4 test code listing ================= using valid = int&; using invalid = float&; template<typename T> valid braces1(decltype(T{0})*); template<typename T> invalid braces1(...); template<typename T> valid braces2(decltype(T{{0}})*); template<typename T> invalid braces2(...); template<typename T> valid braces3(decltype(T{{{0}}})*); template<typename T> invalid braces3(...); valid scalar_1_brace = braces1<int>(0); invalid scalar_2_brace = braces2<int>(0); invalid scalar_3_brace = braces3<int>(0); //int a[1]{{0}}; // GCC error - should be warning valid array_scalar_1_brace = braces1<int[1]>(0); valid array_scalar_2_brace = braces2<int[1]>(0); // GCC error invalid array_scalar_3_brace = braces3<int[1]>(0); struct SS { int n; }; //SS ss{{0}}; // GCC error - should be warning valid struct_scalar_1_brace = braces1<SS>(0); valid struct_scalar_2_brace = braces2<SS>(0); // GCC error invalid struct_scalar_3_brace = braces3<SS>(0); struct SAS { int n[1]; }; //SAS sas{{{0}}}; // GCC error - should be warning valid struct_array_scalar_1_brace = braces1<SAS>(0); valid struct_array_scalar_2_brace = braces2<SAS>(0); valid struct_array_scalar_3_brace = braces3<SAS>(0); // GCC error
This bug is straightforward to confirm. Compile this snippet (-std=c++11 / 14 / 17 / 2a): struct S { int i; }; S s{{0}}; Gives error: braces around scalar initializer for type 'int' Should be a warning (Or, follow the provided compiler explorer link to the test code which includes two more failing cases - array and array member.) The standard is clear that scalar brace init should be accepted: C++14 [dcl.init.aggr]/2 says: "Each member is copy-initialized from the corresponding initializer-clause. [...] [ Note: If an initializer-clause is itself an initializer list, the member is list-initialized, which will result in a recursive application of the rules in this section if the member is an aggregate. — end note ]" C++14 [dcl.init.list]/3.5: "Otherwise, if the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element;" Some historical links leading up to the wording fixes: DR 155. Brace initializer for scalar Explains it was a C/C++ incompatibility pre-11 and points to: DR 632. Brace-enclosed initializer for scalar member of aggregate http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#632 "The initializer-list proposal will resolve this issue..." As stated, it was resolved in C++11 by Initializer Lists: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm 1501. Nested braces in list-initialization http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1501 DR1467 List-initialization of aggregate from same-type object http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 Submitter: Jason Merrill Date: 2012-02-06 [Moved to DR at the November, 2014 meeting.] Please CONFIRM this bug.
The relevant code is: /* It is invalid to initialize a non-aggregate type with a brace-enclosed initializer before C++0x. We need to check for BRACE_ENCLOSED_INITIALIZER_P here because of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is a CONSTRUCTOR (with a record type). */ if (TREE_CODE (stripped_init) == CONSTRUCTOR /* Don't complain about a capture-init. */ && !CONSTRUCTOR_IS_DIRECT_INIT (stripped_init) && BRACE_ENCLOSED_INITIALIZER_P (stripped_init)) /* p7626.C */ { if (SCALAR_TYPE_P (type)) { if (cxx_dialect < cxx11 /* Isn't value-initialization. */ || CONSTRUCTOR_NELTS (stripped_init) > 0) { if (complain & tf_error) error ("braces around scalar initializer for type %qT", type); init = error_mark_node; } } The condition means we give an error for any braced-init-list in C++98, and for a non-empty braced-init-list in later dialects . But the latter condition is wrong, it should allow a single element (and presumably more than one element will be rejected as an invalid initializer anyway). I'm not even sure we should warn about this.
Changing it to a warning, like so: --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6054,15 +6054,19 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p, { if (SCALAR_TYPE_P (type)) { - if (cxx_dialect < cxx11 - /* Isn't value-initialization. */ - || CONSTRUCTOR_NELTS (stripped_init) > 0) + if (cxx_dialect < cxx11) { if (complain & tf_error) error ("braces around scalar initializer for type %qT", type); init = error_mark_node; } + /* No warning for value-initialization. */ + else if (CONSTRUCTOR_NELTS (stripped_init) > 0) + { + warning (0, "braces around scalar initializer for type %qT", + type); + } } else maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); Causes the test code in comment 0 to issue lots of warnings (as expected) but also a new error: 88572.cc:14:40: error: cannot bind non-const lvalue reference of type 'invalid' {aka 'float&'} to an rvalue of type 'float' 14 | invalid scalar_2_brace = braces2<int>(0); | ~~~~~~~~~~~~^~~ Which means that int{{0}} is now accepted, so my patch isn't right.
Right; the patch should only apply within aggregate initialization - arrays and aggregate structures - as the initialization of actual scalars was already correct. I'll take a look now (as I meaning to fix my enum patch this week too).
I don't think reshape_init_r has the context of the type that contains the object being initialized, so might need an extra parameter passed to it.
I guess that the bug persisted so long *because* of the status quo; portable code had to delete extra braces to silence warnings or to compile i.e. the warning on Clang served the purpose of promoting portability to GCC. So, as to whether it should be a warning; I think not, but... for practical portability reasons, it probably should be left as a warning at least until some epoch like C++2a where both GCC & Clang could remove the warning under the -std=c++2a flag. Make sense? FYI My use case is counting aggregate members, similar to fields_count in boost/pfr 'magic_get', but extended to support array members: https://github.com/apolukhin/magic_get/blob/develop/include/boost/pfr/detail/fields_count.hpp That code initializes an aggregate T from an index_sequence I... as T{ ubiq{I}... } (where ubiq is a 'convert to anything' type) To support 'skipping' arrays, you want to initialize the aggregate as T{ {ubiq{I}}...} but, for scalar members, this is what currently fails on GCC / warns on Clang. Another reason that the bug persisted is the general confusion around braces and uniform initialization - this fix will give a generic, uniform, way to initialize the leading members of an aggregate. I wonder if the extra braces should have additional benefits like not allowing narrowing conversions. My limited experiments (on Clang) show no difference.
(In reply to Will Wray from comment #7) > So, as to whether it should be a warning; I think not, but... > for practical portability reasons, it probably should be left as a warning > at least until some epoch like C++2a where both GCC & Clang could remove > the warning under the -std=c++2a flag. Make sense? No, I don't think so. I don't see why the warning should be given for C++11 but not C++2a when the code is valid for both. I think it should be accepted without a warning. I'd be more inclined to say it should be accepted in C++98 with a -pedantic warning, rather than give a warning for C++11. > I wonder if the extra braces should have additional benefits like not > allowing > narrowing conversions. My limited experiments (on Clang) show no difference. The outermost braces already mean it's a context that doesn't allow narrowing, so the additional inner braces make no difference.
The patch below seems to work as far as I've tested - please review. It looks like the bool first_initializer_p argument to reshape_init_r gives the context that is needed, according to the function comment; /* ... FIRST_INITIALIZER_P is true if this is the first initializer of the outermost CONSTRUCTOR node. */ If I read this right then this bool arg is true for scalar init and false when initializing a scalar member of an aggregate (class or array). The patch below rejects int ii{{0}}; --- gcc/cp/decl.c +++ gcc/cp/decl.c @@ -6054,16 +6054,19 @@ reshape_init_r (tree type, reshape_iter { if (SCALAR_TYPE_P (type)) { - if (cxx_dialect < cxx11 - /* Isn't value-initialization. */ - || CONSTRUCTOR_NELTS (stripped_init) > 0) + if (cxx_dialect < cxx11 || first_initializer_p) { if (complain & tf_error) error ("braces around scalar initializer for type %qT", type); init = error_mark_node; } - } + else if (CONSTRUCTOR_NELTS (stripped_init) > 0) + { + warning (0, "braces around scalar initializer for type %qT", + type); + } + } else maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS); }
Re: warnings; I certainly prefer to have this accepted with no warning (i.e. remove the 'else if' warning in the patch above). Saves having to disable the warning in GCC, as I have to do in Clang.
(In reply to Will Wray from comment #9)
> The patch below seems to work as far as I've tested - please review.
>
> It looks like the bool first_initializer_p argument to reshape_init_r
> gives the context that is needed, according to the function comment;
>
> /* ...
> FIRST_INITIALIZER_P is true if this is the first initializer of the
> outermost CONSTRUCTOR node. */
>
> If I read this right then this bool arg is true for scalar init and
> false when initializing a scalar member of an aggregate (class or array).
I understood it to mean something like {{1}, 2} is the first,
^^^
but apparently not. The patch works for me, but I can't review it properly.
On further investigation the logic of using first_initializer_p looks correct.
The comment on reshape_init suggests that it wasn't intended for scalar init:
/* Undo the brace-elision allowed by [dcl.init.aggr] in a
brace-enclosed aggregate initializer.
INIT is the CONSTRUCTOR containing the list of initializers describing
a brace-enclosed initializer for an entity of the indicated aggregate TYPE.
In fact, reshape_init is used more broadly to error-check braced-init-list -
- the first substantive case is direct enum init, a scalar init special-case.
Perhaps the general scalar case should be dealt with here at the top level.
Instead the recursive call to reshape_init_r is done next
setting first_initializer_p to true - the only place it is set true
(the true value will be forwarded to reshape_init_class for class type).
So, for a scalar init, the tree type passed to reshape_init is SCALAR_TYPE_P.
This is passed down to reshape_init_r with first_initializer_p set true.
Entering reshape_init_r we have
if (first_initializer_p && !CP_AGGREGATE_TYPE_P (type)
&& has_designator_problem (d, complain))
return error_mark_node;
Here, first_initializer_p && !CP_AGGREGATE_TYPE_P (type) covers scalar init
(and other non-aggregate init).
Arriving at our block, we also enter a context requiring a single-initializer
/* A non-aggregate type is always initialized with a single
initializer. */
if (!CP_AGGREGATE_TYPE_P (type))
and then further filter down to CONSTRUCTOR with BRACE_ENCLOSED_INITIALIZER_P
and, specifically of SCALAR_TYPE_P
if (TREE_CODE (stripped_init) == CONSTRUCTOR
/* Don't complain about a capture-init. */
&& !CONSTRUCTOR_IS_DIRECT_INIT (stripped_init)
&& BRACE_ENCLOSED_INITIALIZER_P (stripped_init)) /* p7626.C */
{
if (SCALAR_TYPE_P (type))
> I understood it to mean something like {{1}, 2} is the first,
> ^^^
Me too, but taking "outermost CONSTRUCTOR node" to mean the actual outer type
here (first_initializer_p==true) and with only a single scalar initializer:
like scalar_type{{1}} not { {1} }
^^^ scalar_type^^^
So, I've convinced myself that my patch follows the existing logic.
It'd be good to get review from someone not suffering from confirmation bias.
Re-reviewing, I notice that the patch I posted in comment #9
now rejects nested empty-brace scalar init:
int i{{}};
which was previously accepted. So we'll need a decision on this too.
Clang rejects with -pedantic-errors or warns otherwise:
pedantic error / warning: too many braces around scalar initializer
MSVC rejects:
error: 'initializing': cannot convert from 'initializer list' to 'int'
note: Too many braces around initializer for 'int'
I reckon that Clang is right to reject under -pedantic, else accept and warn
This Quora post comes to a similar conclusion:
https://www.quora.com/Is-double-braced-scalar-initialization-allowed-by-the-C-standard-int-x
>accepting {{}} for int seems like a harmless language extension.
I intend to submit a patch, or two patches, for these scalar braced init issues: Case 1: GCC rejects braced-init of scalars in aggregates. It should accept. Case 2: GCC accepts empty braced-init of scalars (comment 13). It should reject. Fixing case 2 has the potential to break code. Such broken code is already rejected by Clang and MSVC. It seems unlikely that there will be any examples of this in the wild. Both case 1 and case 2 are fixed by the patch in comment 9. The patch needs to be updated to give a warning only when appropriate. I plan to submit a single patch to fix both issues. A more cautious approach would be to submit 2 separate patches. Please speak now if you'd prefer to see 2 patches.
Created attachment 45683 [details]
Proposed patch including updated tests
Accept braces around scalar initializer within aggregate init,
previously rejected; this patch accepts without a warning.
Reject braced empty-brace value-initialization of scalar variable
previously accepted.
Maintain C++98 rejection of scalar braced-init.
See Bug 88572 for details, standards links and extra test code.
Log:
PR c++/88572
* decl.c (reshape_init_r): Remove condition that was incorrectly
rejecting braces around scalar initializer within aggregate init.
Produce no warning. Replace with condition rejecting braced-init
of scalar variable, including empty-brace value-initialization
that was being incorrectly accepted. Produce same error for both.
PR c++/88572
* g++.dg/cpp0x/initlist69.C: Update 2 tests; changed error, OK.
* g++.dg/cpp1z/direct-enum-init1.C: Update 3 tests; changed error.
* g++.dg/init/brace1.C: Update 1 test; error only on c++98. Add
1 test with one more set of braces; error on too many braces.
* g++.dg/init/brace2.C: Add 1 test; empty-brace scalar init fail.
* g++.dg/init/union2.C: Update 1 test; error only on c++98. Add
1 test with one more set of braces; error on too many braces.
* g++.dg/warn/Wbraces2.C: Update 3 test; 1 error only on c++98.
2 now give invalid conversion instead of braces error on >98.
Created attachment 45778 [details]
Updated patch addressing review comments
(Updated Change Log entry for decl.c)
Log:
PR c++/88572
* decl.c (reshape_init_r): Remove condition that was incorrectly
rejecting braces around scalar initializer within aggregate init.
Produce no warning. Add a conditional block rejecting braced-init
of scalar variable, including empty-brace value-initialization
that was being incorrectly accepted.
Author: jason Date: Wed Feb 20 18:50:32 2019 New Revision: 269045 URL: https://gcc.gnu.org/viewcvs?rev=269045&root=gcc&view=rev Log: PR c++/88572 - wrong handling of braces on scalar init. * decl.c (reshape_init_r): Allow braces around scalar initializer within aggregate init. Reject double braced-init of scalar variable. Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/decl.c trunk/gcc/testsuite/g++.dg/cpp0x/initlist69.C trunk/gcc/testsuite/g++.dg/cpp1z/direct-enum-init1.C trunk/gcc/testsuite/g++.dg/init/brace1.C trunk/gcc/testsuite/g++.dg/init/brace2.C trunk/gcc/testsuite/g++.dg/init/union2.C trunk/gcc/testsuite/g++.dg/warn/Wbraces2.C
Fixed in GCC 9.
*** Bug 95559 has been marked as a duplicate of this bug. *** |
у меня есть таблица поиска, как определено ниже, и я использую GCC. Когда я компилирую, я получаю предупреждения как
warning: braces around scalar initializer
что означает это предупреждение? Как инициализировать этот LUT? Я делаю ошибку, инициализируя эти структуры?
помогите!!
typedef struct TECH
{
float velocity1, velocity2;
float temp;
float measure;
int id;
float storage[64];
}TECH;
struct TECH lut_model_1[2] = {{{296.001465},
{74.216972},
{2.025908},
{1.516384},
{1},
{0.001746,
0.000256, 0.006216, 0.005249, -0.001668, -0.001377, 0.009865, 0.010454, -0.000288, -0.005853, 0.010584, 0.015440, 0.000465, -0.000602, 0.004330, 0.005700, 0.017120,
0.233015, 0.034154, 0.244022, 0.007644, 0.385683, 0.042960, 0.406633, -0.007811, 0.346931, 0.040123, 0.387361, 0.007030, 0.225309, 0.017897, 0.241024, 0.003700,
0.103601, 0.060748, 0.121059, -0.045041, 0.076974, 0.070647, 0.148810, -0.022399, 0.074007, 0.054797, 0.141794, 0.010376, 0.052482, 0.045013, 0.078443, -0.019940,
-0.057353, 0.044285, 0.066622, -0.058232, -0.093817, 0.064753, 0.126611, -0.008286, -0.085634, 0.029582, 0.140443, 0.009189, -0.052974, 0.036057, 0.087536}},
{{309.270569},
{74.520226},
{2.088673},
{1.595730},
{1},
{-0.003261,
0.001452, 0.006673, 0.007092, 0.001020, 0.002904, 0.009037, 0.009587, -0.001494, 0.000296, 0.009327, 0.010013, -0.000301, -0.002727, 0.005875, 0.008888, -0.016850,
0.231185, 0.029758, 0.241629, 0.009411, 0.382748, 0.057553, 0.407984, -0.019496, 0.393691, 0.045355, 0.411033, -0.019787, 0.185746, 0.027101, 0.216863, 0.010189,
0.050463, 0.041380, 0.059462, 0.009747, 0.093188, 0.089831, 0.132579, -0.049612, 0.058789, 0.075130, 0.122026, -0.022185, 0.017041, 0.035450, 0.074255, -0.002068,
-0.061219, 0.040752, 0.087084, -0.013021, -0.106098, 0.066566, 0.140099, -0.041966, -0.073433, 0.055231, 0.125908, -0.003481, -0.050690, 0.017257, 0.085251}}};
5 ответов
вы должны удалить скобки: {
и }
вокруг одного значения.
struct TECH lut_model_1[2] = {{296.001465,
74.216972,
2.025908,
1.516384,
1,
{0.001746,
0.000256, 0.006216, 0.005249, -0.001668, -0.001377, 0.009865, 0.010454, -0.000288, -0.005853, 0.010584, 0.015440, 0.000465, -0.000602, 0.004330, 0.005700, 0.017120,
0.233015, 0.034154, 0.244022, 0.007644, 0.385683, 0.042960, 0.406633, -0.007811, 0.346931, 0.040123, 0.387361, 0.007030, 0.225309, 0.017897, 0.241024, 0.003700,
0.103601, 0.060748, 0.121059, -0.045041, 0.076974, 0.070647, 0.148810, -0.022399, 0.074007, 0.054797, 0.141794, 0.010376, 0.052482, 0.045013, 0.078443, -0.019940,
-0.057353, 0.044285, 0.066622, -0.058232, -0.093817, 0.064753, 0.126611, -0.008286, -0.085634, 0.029582, 0.140443, 0.009189, -0.052974, 0.036057, 0.087536}},
{309.270569,
74.520226,
2.088673,
1.595730,
1,
{-0.003261,
0.001452, 0.006673, 0.007092, 0.001020, 0.002904, 0.009037, 0.009587, -0.001494, 0.000296, 0.009327, 0.010013, -0.000301, -0.002727, 0.005875, 0.008888, -0.016850,
0.231185, 0.029758, 0.241629, 0.009411, 0.382748, 0.057553, 0.407984, -0.019496, 0.393691, 0.045355, 0.411033, -0.019787, 0.185746, 0.027101, 0.216863, 0.010189,
0.050463, 0.041380, 0.059462, 0.009747, 0.093188, 0.089831, 0.132579, -0.049612, 0.058789, 0.075130, 0.122026, -0.022185, 0.017041, 0.035450, 0.074255, -0.002068,
-0.061219, 0.040752, 0.087084, -0.013021, -0.106098, 0.066566, 0.140099, -0.041966, -0.073433, 0.055231, 0.125908, -0.003481, -0.050690, 0.017257, 0.085251}}};
не даст никакого предупреждения.
в языке C совершенно законно использовать дополнительные фигурные скобки при инициализации скалярного значения, как в
int x = { 5 };
даже если вы обычно не увидеть это в реальном коде. В вашем случае вы делаете то же самое, за исключением того, что в вашем случае скалярное значение является членом большей совокупности.
GCC генерирует предупреждения для такого кода. Он считает, что возможно, что вы написали что-то, что вы не собирались писать, так как брекеты большую часть времени используется для запуска многосоставного инициализатора для агрегата, а не автономного инициализатора для скаляра.
<rant>
GCC определенно портит вещи своими предупреждениями о фигурных скобках в агрегатных инициализаторах. На языке C { 0 }
всегда использовался в качестве идиоматического универсального нулевого инициализатора. По крайней мере!—2—> должен был быть освобожден от предупреждений, связанных с скобками, для его идиоматического значения.</rant>
это скалярный инициализатор:int foo = 3;
Это скалярный инициализатор с фигурными скобками вокруг него:int foo = {3};
Это инициализатор массива, который не является скалярным:int foo[] = {1, 2, 3};
в предупреждении говорится, что ваша структура имеет скалярные инициализаторы с фигурными скобками вокруг них:
typedef struct TECH
{
float velocity1, velocity2;
...
struct TECH lut_model_1[2] = {{{296.001465},
{74.216972},
...
ваш код будет работать, он просто имеет лишние скобки вокруг своих скалярных инициализаторов. Если вы вытащите фигурные скобки и отформатируете их немного более красиво (я бы поставил первый инициализатор его собственная линия) в этом не будет ничего предосудительного.
это означает, что вам не нужно ставить фигурные скобки в таких местах, как:
{74.216972},
в принципе, все фигурные скобки, которые у вас есть, являются необязательными (кроме внешних), однако вы получите другое предупреждение за не охватывающие вложенные структуры в инициализаторе. В принципе, если вы не против предупреждения, поместите фигурные скобки только вокруг вложенных структур и массивов; если нет, используйте их для улучшения читаемости, как вам нравится.
вы инициализируете скалярные значения (velocity1, temp и т. д.), окружая их фигурными скобками, что не требуется.
попробуйте это:
struct TECH lut_model_1[2] = {{296.001465,
74.216972,
2.025908,
1.516384,
1,
{0.001746,
0.000256, 0.006216, 0.005249, -0.001668, -0.001377, 0.009865, 0.010454, -0.000288, -0.005853, 0.010584, 0.015440, 0.000465, -0.000602, 0.004330, 0.005700, 0.017120,
0.233015, 0.034154, 0.244022, 0.007644, 0.385683, 0.042960, 0.406633, -0.007811, 0.346931, 0.040123, 0.387361, 0.007030, 0.225309, 0.017897, 0.241024, 0.003700,
0.103601, 0.060748, 0.121059, -0.045041, 0.076974, 0.070647, 0.148810, -0.022399, 0.074007, 0.054797, 0.141794, 0.010376, 0.052482, 0.045013, 0.078443, -0.019940,
-0.057353, 0.044285, 0.066622, -0.058232, -0.093817, 0.064753, 0.126611, -0.008286, -0.085634, 0.029582, 0.140443, 0.009189, -0.052974, 0.036057, 0.087536}},
{309.270569,
74.520226,
2.088673,
1.595730,
1,
{-0.003261,
0.001452, 0.006673, 0.007092, 0.001020, 0.002904, 0.009037, 0.009587, -0.001494, 0.000296, 0.009327, 0.010013, -0.000301, -0.002727, 0.005875, 0.008888, -0.016850,
0.231185, 0.029758, 0.241629, 0.009411, 0.382748, 0.057553, 0.407984, -0.019496, 0.393691, 0.045355, 0.411033, -0.019787, 0.185746, 0.027101, 0.216863, 0.010189,
0.050463, 0.041380, 0.059462, 0.009747, 0.093188, 0.089831, 0.132579, -0.049612, 0.058789, 0.075130, 0.122026, -0.022185, 0.017041, 0.035450, 0.074255, -0.002068,
-0.061219, 0.040752, 0.087084, -0.013021, -0.106098, 0.066566, 0.140099, -0.041966, -0.073433, 0.055231, 0.125908, -0.003481, -0.050690, 0.017257, 0.085251}}};
У меня есть справочная таблица, как определено ниже, и я использую GCC. Когда я компилирую, я получаю предупреждения как
warning: braces around scalar initializer
Что означает это предупреждение? Как мне инициализировать эту LUT? Я делаю ошибку при инициализации этих структур?
Помощь!
typedef struct TECH
{
float velocity1, velocity2;
float temp;
float measure;
int id;
float storage[64];
}TECH;
struct TECH lut_model_1[2] = {{{296.001465},
{74.216972},
{2.025908},
{1.516384},
{1},
{0.001746,
0.000256, 0.006216, 0.005249, -0.001668, -0.001377, 0.009865, 0.010454, -0.000288, -0.005853, 0.010584, 0.015440, 0.000465, -0.000602, 0.004330, 0.005700, 0.017120,
0.233015, 0.034154, 0.244022, 0.007644, 0.385683, 0.042960, 0.406633, -0.007811, 0.346931, 0.040123, 0.387361, 0.007030, 0.225309, 0.017897, 0.241024, 0.003700,
0.103601, 0.060748, 0.121059, -0.045041, 0.076974, 0.070647, 0.148810, -0.022399, 0.074007, 0.054797, 0.141794, 0.010376, 0.052482, 0.045013, 0.078443, -0.019940,
-0.057353, 0.044285, 0.066622, -0.058232, -0.093817, 0.064753, 0.126611, -0.008286, -0.085634, 0.029582, 0.140443, 0.009189, -0.052974, 0.036057, 0.087536}},
{{309.270569},
{74.520226},
{2.088673},
{1.595730},
{1},
{-0.003261,
0.001452, 0.006673, 0.007092, 0.001020, 0.002904, 0.009037, 0.009587, -0.001494, 0.000296, 0.009327, 0.010013, -0.000301, -0.002727, 0.005875, 0.008888, -0.016850,
0.231185, 0.029758, 0.241629, 0.009411, 0.382748, 0.057553, 0.407984, -0.019496, 0.393691, 0.045355, 0.411033, -0.019787, 0.185746, 0.027101, 0.216863, 0.010189,
0.050463, 0.041380, 0.059462, 0.009747, 0.093188, 0.089831, 0.132579, -0.049612, 0.058789, 0.075130, 0.122026, -0.022185, 0.017041, 0.035450, 0.074255, -0.002068,
-0.061219, 0.040752, 0.087084, -0.013021, -0.106098, 0.066566, 0.140099, -0.041966, -0.073433, 0.055231, 0.125908, -0.003481, -0.050690, 0.017257, 0.085251}}};
OrmaJever 9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
||||||||
1 |
||||||||
27.01.2013, 19:44. Показов 5689. Ответов 13 Метки нет (Все метки)
Вобщем то был обычный масив строк
Но масив этот большой, а в нём приходится искать определёное слово много раз, поэтому решил поделить этот масив на двухмерный с групировкой по первой букве.
Строк на каждую букву разное количество (если что) Код warning: braces around scalar initializer warning: (near initialization for 'someName[0]') warning: excess elements in scalar initializer warning: (near initialization for 'someName[0]') warning: excess elements in scalar initializer ......... и так по каждому слову. Я понимаю что нужно как-то обьявить масив по другому, но как только не пробовал, ошибки не пропадают. Читал на эту тему stackoverflow но там примеры с интами и пользовательскими структурами, но указатели на char как я понимаю немного запутанее.
__________________
0 |
lowercase 213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
||||
27.01.2013, 21:38 |
2 |
|||
но указатели на char как я понимаю немного запутанее не то чтобы уж очень так. просто нужно чуток выделить память, а потом и чуток освободить. примерно так:
1 |
OrmaJever 9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
||||
27.01.2013, 21:56 [ТС] |
3 |
|||
ойойой, не, так не годись. А как синтаксически верно в рантайме можно динамически получить имя переменой?Тоесть тогда разобью на несколько простоых масивов типа
и нужно будет собрать имя масива взависимости от буквы, тоесть someName+(*word-0x61) (*word-0x61) — это типо некая буква вычисляемая в рантайме. Или может предложите лучший вариант? Просто вариант с выделением памяти мне не очень нравится.
0 |
213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
|
27.01.2013, 22:04 |
4 |
а именованные константы? загнать индексы под имя. не? Добавлено через 7 минут
Просто вариант с выделением памяти мне не очень нравится. ну в любом случаее память будет выделятся. просто сдесь она выделяется динамически(на этапе выполнения)
0 |
9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
|
27.01.2013, 22:11 [ТС] |
5 |
а именованные константы? загнать индексы под имя. не? Добавлено через 7 минут ну в любом случаее память будет выделятся. просто сдесь она выделяется динамически(на этапе выполнения) Можно пример? Ато я не понял что это и как) Добавлено через 2 минуты
а именованные константы? загнать индексы под имя. не? Добавлено через 7 минут ну в любом случаее память будет выделятся. просто сдесь она выделяется динамически(на этапе выполнения) Ну я и имел это в виду, просто не хочу ввидеть у себя в коде видеть вложеные циклы, кучу выделений памяти из-за какой то мелочи которая может выполнится сама.
0 |
lowercase 213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
||||
27.01.2013, 22:19 |
6 |
|||
обычный define, ну например вот так:
Добавлено через 2 минуты Добавлено через 2 минуты
Ну я и имел это в виду, просто не хочу ввидеть у себя в коде видеть вложеные циклы, кучу выделений памяти из-за какой то мелочи которая может выполнится сама. ну тогда может ктото другой подскажет вам чтото. а так в общем варнинг это не ошибка. с ним программа работать будет тоже.
0 |
OrmaJever 9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
||||
27.01.2013, 22:31 [ТС] |
7 |
|||
ну можно в общем и выделить просто память под масивы строк точно так же как я показал выше. ага, значит вы меня не совсем поняли. Обычный одномерный масив который содержит все слова компилируется нормально и работает так же
А те самый ошибки появляются только при создании двухмерного масива как написал в первом посте. В том то и суть что под одномерный масив я не выделял память, поэтмоу немного удивился что под двухмерный уже нужны такие изменения. Добавлено через 1 минуту
0 |
lowercase 213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
||||
28.01.2013, 00:40 |
8 |
|||
тьфу! что же я раньше не додумался! двухмерный масив строк — это же трехмерный масив символов вот оно ваше(и мое вместе с вами ) щастье:
ни каких предупреждений и ошибок, все компилируется и выполняется на ура. и скрин есть тому подтверждение Миниатюры
1 |
OrmaJever 9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
||||||||
28.01.2013, 01:17 [ТС] |
9 |
|||||||
но ведь есть один нюанс который я описал в первом посте
Строк на каждую букву разное количество (если что) Тоесть подмасивов будет 26 (буквы англ алфавита), но вот слов в каждом из них разное количество и слова эти разумеется тоже разного размера поэтому я не могу указать размер в двух последних скобках, а такой вариант не прокатывает
Код error: array type has incomplete element type А казалось бы задача то простейшая, слова статичны и заранее извесны… но это же си… Добавлено через 1 минуту
Компилится но ошибки из первого поста остаются
0 |
lowercase 213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
||||
28.01.2013, 01:25 |
10 |
|||
стопачки.. а ведь вот так тоже скомпилировалось:
странно, я вроде с самого начала так пробовал и не получалось. черт его знает может где забыл чтото. Добавлено через 1 минуту Добавлено через 2 минуты Кликните здесь для просмотра всего текста «/usr/bin/make» -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .clean-conf CLEAN SUCCESSFUL (total time: 2s) «/usr/bin/make» -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf BUILD SUCCESSFUL (total time: 3s)
1 |
9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
|
28.01.2013, 01:32 [ТС] |
11 |
У меня так тоже компилируется если я задам во вторых скобках количество слов, но ведь оно в разных масивах разное, не плохо ли это? Например
0 |
lowercase 213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
||||
28.01.2013, 01:42 |
12 |
|||
а колличество слов известно на этапе компиляции или определяется в рантайме? Добавлено через 2 минуты Добавлено через 5 минут
но это будет не то. тут колличество строк матрицы, а не строк символов низвенстно. то есть здесь MATRIX_N задает колличество строк на строку марицы. по моему вам остается только указатели и выделение памяти. или указание памяти с запасом при инициализации
0 |
9 / 9 / 0 Регистрация: 10.11.2011 Сообщений: 241 |
|
28.01.2013, 01:54 [ТС] |
13 |
а колличество слов известно на этапе компиляции или определяется в рантайме? Конешно, И количество и сами слова известны при компиляции, это просто статичный перечень слов по которым в рантайме будет ити поиск, что бы каждый раз не проходить все слова (их более 5тыс) решил разделить их по первым буквам, вот собствено и тема об этом.
0 |
lowercase 213 / 202 / 85 Регистрация: 09.05.2012 Сообщений: 494 |
||||
28.01.2013, 02:09 |
14 |
|||
Ну чтож, воспользовался избыточным выделением, хрен с ней с этой памятью. погодите вешать нос вот вам моя последняя отчаяная попытка помочь:
Миниатюры
1 |