The warning is produced by the c code generated by vala.
warning: missing braces around initializer
The code works but the warning is annoying. The vala code referenced by the warning is
struct Position {uint x; uint y;}
private static Position positions[8];
The generated C code is
static Position det_positions[8] = {0};
I've tried initializing positions half a dozen different ways but can't seem to get the syntax to satisfy the warning. Is this GCC bug 53119 or is there a way to fix it?
Yes, this appears to be related to GCC bug 53119. It goes away if you change the C declaration to {{0}}. Your options are:
Ignore the warning.
Manipulate the C code after generation to have {{0}} instead of {0} on that line using sed or the like.
Declare the array extern in Vala, and write the C definition elsewhere. (The permanent version of #2.)
Do something like struct foo { int bar; Position positions[8]; } static foo position_holder and {0} will then be initialising position_holder.bar which is fine and the warning goes away.
This warning also appears when a multi-dimensional array is treated as a linear array ( although it is still correct and the code runs perfectly ) with -Wall compiler flags set.
For example
char array[5][10][2] = {\
"0","0","0","0","0","0","0","0","0","0",\
"1","1","1","1","1","1","1","1","1","1",\
"2","2","2","2","2","2","2","2","2","2",\
"3","3","3","3","3","3","3","3","3","3",\
"4","4","4","4","4","4","4","4","4","4" };
This will generate the warning.
Do the following changes to remove the warnings as shown below
char array[5][10][2] = {\
{"0","0","0","0","0","0","0","0","0","0" },\
{"1","1","1","1","1","1","1","1","1","1"},\
{"2","2","2","2","2","2","2","2","2","2"},\
{"3","3","3","3","3","3","3","3","3","3"},\
{"4","4","4","4","4","4","4","4","4","4"} };
Please do correct me if I am wrong.
Related
If I have a function foo() and use -ffunction-sections, gcc will place foo() inside its own .text.foo section. Is it possible to change the prefix of .text? Such that I get .customName.foo instead of text.foo.
I have the same problem, and I solved it using the section attribute.
The following solution is the simplest but does not create a section for each function (as the -ffunction-section parameter allows to do)
#define AT_FLASH_TEXT_SECTION(var) \
__attribute__((section(".text.flash"))) var
AT_FLASH_TEXT_SECTION(int myFunction(float param1, long param2));
So the function myFunction will appear in the section .text.flash, but also all other functions that are declared using the macro AT_FLASH_TEXT_SECTION.
To get the desired behavior I modified the macro as follows:
#define AT_FLASH_TEXT_SECTION_SYM(var, subsectionName) \
__attribute__((section(".text.flash." #subsectionName))) var
AT_FLASH_TEXT_SECTION_SYM(int myNewFunction(float param1, long param2), myNewFunction);
This is the best solution I've found so far.
Unfortunately, it is error-prone: the function name must be repeated identically in the subsectionName parameter of the AT_FLASH_TEXT_SECTION_SYM macro.
Furthermore, if two c modules contain two static functions with the same name, they will be emitted in the same section, going back to the previous problem.
I hope this helps, and maybe you can find a better solution starting from this.
No, that does not seem possible. See gcc/varasm.c (I haven't run the debugger, but am fairly sure this is the code that computes section names.)
void
default_unique_section (tree decl, int reloc)
{
[...]
switch (categorize_decl_for_section (decl, reloc))
{
case SECCAT_TEXT:
prefix = one_only ? ".t" : ".text";
break;
[...]
name = IDENTIFIER_POINTER (id);
name = targetm.strip_name_encoding (name);
[...]
string = ACONCAT ((linkonce, prefix, ".", name, NULL));
set_decl_section_name (decl, string);
}
Besides, that might be a bad idea, as e.g. linker scripts treat sections based on their names (see ld --verbose). Something like .text.customprefix.foo might be a better choice, but I don't know why you want custom prefices.
As a workaround, you can assign sections manually with the section attribute.
'section ("SECTION-NAME")'
Normally, the compiler places the code it generates in the 'text'
section. Sometimes, however, you need additional sections, or you
need certain particular functions to appear in special sections.
The 'section' attribute specifies that a function lives in a
particular section. For example, the declaration:
extern void foobar (void) __attribute__ ((section ("bar")));
puts the function 'foobar' in the 'bar' section.
The following code outputs different results on various compilers:
2,1,2 on Visual Studio 2013
2,2,2 on Visual Studio 2015
2,1,1 on GCC5/c++14
2,2,2 on Clang 3.7 with Microsoft Codegen
2,1,2 on Clang 3.6/c++11 under Ubuntu 14.04
Finally, how it should work according to C++ standard?
#include <iostream>
#include <vector>
#include <stdio.h>
using namespace std;
class Value;
using Array = std::vector<Value>;
class Value
{
public:
Value(const Array &)
{
}
Value(int)
{
}
};
void foo(Array const& a)
{
printf("%d\n", (int)a.size());
}
int main()
{
Array a1 = { 1, 2 };
foo(a1);
foo(Array{ a1 });
foo(Array({ a1 }));
}
P.S. The same issue reveals with json_spirit library from this article: http://www.codeproject.com/Articles/20027/JSON-Spirit-A-C-JSON-Parser-Generator-Implemented
Your program is ill-formed in C++11, as you have created a std::vector type with an incomplete type as an argument. The value type of a vector must be complete when you create the std::vector<T> type.
As an ill-formed program (and I'm not aware of a requirement for a diagnostic), any and all behavior is legal under the standard.
The requirement that vector's T be a complete type is probably over-specified (there is really no convincing reason to have that requirement), but it exists. Asking the same question in C++1z will lead to a different answer, as that requirement was relaxed.
Ignoring that issue, philosophically:
Array a1 = { 1, 2 };
this should generate a std::vector with two elements.
foo(a1);
This should pass a1 to foo, as the types match exactly.
foo(Array{ a1 });
Here we have {}. My rule of thumb with {} is "if it is non-empty, and it can match an initializer_list constructor, it must".
As a1 can be converted to a Value, Array{ a1 } is an array of one Value.
foo(Array({ a1 }));
Here we look at an argument of the constructor Array that can be called with { a1 }. Both the std::initalizer_list<Value> and the Array&& constructors can be.
Which is called should not matter: The Array&& constructor in turn sends the {a1} to the std::initalizer_list<Value> constructor.
So my opinion is that it should print 211. This is, however, merely an opinion on what the could ought to do, not an analysis of what the standard says it should do, as the C++11 standard quite clearly states your program is ill-formed.
On the other hand, hiding the copy constructor seems rude.
On the final hand, you did write a simply insane type. Insane behavior is to be expected.
A more practical concern might be when the Value type has a template constructor that happens to also match a std::vector<Value>.
In C++11, compilers' determination to match braced initializers with constructors taking std::initializer_lists is so strong, it prevails even if the best-match std::initializer_list constructor can't be called (Scott Meyers).
Array a1 = { 1, 2 }; // Call Initiliazer list constructor foo(a1); // print 2
foo(Array{ a1 }); // Call Initiliazer list constructor. Print 1
foo(Array({ a1 })); // Call Initiliazer list constructor. Print 1
According to the standard, the result must be: 2,1,1
Yakk's answer mention that the program is ill-formed in C++11. But this post is very interesting.
I want to know data type using variable name
My final goal is getting a function signature for making a function stub(skeleton code)
but GCC error message just notify only undefined function name
Can I see a symbol table? (for inferencing function signature)
for example, foo.c is like below
#include <stdio.h>
int main() {
int n = 0;
n = foo();
return 0;
}
I want to make a function stub
so I want to know function foo has no parameter and returns an integer value
What should I do?
I think below:
linker error message say function foo is undefined
read line 5
n = foo();
inspect type of n using symbol table
is it right?
sorry for my bad english
please teach me inferencing a function signature
Inject his code into your source file:
typedef struct { int a; char c; } badtype_t;
badtype_t badtype;
then replace the error line like this:
n = badtype; //foo();
or if you want the type foo returns:
badtype = foo();
then you will get some error like this:
incompatible types when initializing type ‘int’ using type ‘badtype_t’
and you can get the type int.
or if you want the type of foo itself:
foo * 2
then you will get some error like this:
invalid operands to binary * (have 'int (*)()' and 'int')
and you can get the type int (*)() (that is, function taking nothing and returning an int).
It seems ok, but this strategy will not be good enough. Using the left-hand side of an expression is not enough to determine the return-type of the function. In particular, there may be no left-hand side at all, simply: foo();. What then?
If you just want to see a symbol table, that's what nm is for.
For example, if you get an error linking foo.o and bar.o together, you can do this:
nm -a foo.o
That will show you all the symbols defined in module foo.
But I don't see why you think this would help. C symbols do not have any type information. There may be enough metadata to distinguish extern linkage, and/or to tell whether a symbol function or data, but that's it. There is no way to tell an int from a float, or a function taking two ints and returning a double from a function taking a char * and returning a different char *.
So, you have some function named foo defined somewhere, and you want to know what its type is.
If you don't actually have a prototype for foo somewhere in your #included header files, this is easy:
If you're using C99, your code is invalid.
Otherwise, foo must take no arguments and return int, or your code is invalid.
And this isn't one of those "technically invalid, but it works on every platform" cases; it will break. For example, with gcc 4.2 for 64-bit x86 linux or Mac, if you do this:
double foo(double f) { return f*2; }
Then, without a header file, call it like this:
double f = foo(2.0);
printf("%f\n", f);
If compiled as C89, this will compile and link just fine (clang or gcc 4.8 will give you a warning; gcc 4.2 won't even do that by default), and run, and print out 2.0. At least on x86_64; on ARM7, you'll corrupt the stack, and segfault if you're lucky. (Of course it actually does double something—either your 2.0 or some random uninitialized value—but it can't return that to you; it's stashed it in an arbitrary floating-point register that the caller doesn't know to access.)
If it is in a header file, you can always search for it. emacs, graphical IDEs, etc. are very good at this. But you can use the compiler to help you out, in two ways.
First, just do this:
gcc -E main.c > main.i
less main.i
Now search for /foo, and you'll find it.
Or you can trick the compiler into giving you an error message, as in perreal's answer.
I develop using Geany 1.22 and I am having trouble with coloration of C++11 keywords.
Here is my configuration file for .cpp : filetypes.cpp
# For complete documentation of this file, please see Geany's main documentation
[styling]
# foreground;background;bold;italic
default=default
comment=comment
commentline=comment
commentdoc=commentdoc
number=number
word=keyword
word2=keyword2
string=string
character=character
uuid=extra
preprocessor=preprocessor
operator=operator
identifier=default
stringeol=stringeol
# #"verbatim"
verbatim=extra
# (/regex/)
regex=extra
commentlinedoc=commentdoc
commentdockeyword=commentdoc
commentdockeyworderror=commentdoc
globalclass=type
[keywords]
# all items must be in one line
primary=and and_eq asm auto bitand bitor bool break case catch char class compl const const_cast continue default delete do double dynamic_cast else enum explicit export extern false float for friend goto if inline int long mutable namespace new not not_eq operator or or_eq private protected public register reinterpret_cast return short signed sizeof static static_cast struct switch template this throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while xor xor_eq static_assert decltype
secondary=
# these are some doxygen keywords (incomplete)
docComment=attention author brief bug class code date def enum example exception file fn namespace note param remarks return see since struct throw todo typedef var version warning union
[lexer_properties]
styling.within.preprocessor=1
preprocessor.symbol.$(file.patterns.cpp)=#
preprocessor.start.$(file.patterns.cpp)=if ifdef ifndef
preprocessor.middle.$(file.patterns.cpp)=else elif
preprocessor.end.$(file.patterns.cpp)=endif
[settings]
lexer_filetype=C
# default extension used when saving files
extension=cpp
# the following characters are these which a "word" can contains, see documentation
#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
# if only single comment char is supported like # in this file, leave comment_close blank
comment_open=//
comment_close=
# this is an alternative way, so multiline comments are used
#comment_open=/*
#comment_close=*/
# set to false if a comment character/string should start at column 0 of a line, true uses any
# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d
#command_example();
# setting to false would generate this
# command_example();
# This setting works only for single line comments
comment_use_indent=true
# context action command (please see Geany's main documentation for details)
context_action_cmd=
[build_settings]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
compiler=g++ -Wall -c "%f"
linker=g++ -Wall -o "%e" "%f"
run_cmd="./%e"
If I write :
class MyClass
{
};
to define a new class, then the color of MyClass is set to the color of globalclass (which is the color associated to type)
But when I write in C++11 :
class MyClass final
{
};
then final (and not MyClass) is set to the color of globalclass. If I add final to the list of primary keywords, then it is set to the color of word which is good, but MyClass is still not interpreted as a globalclass.
How to solve that problem ?
The problem seems to be that in C++11, final and override (I suspect you will have the same problem there) are not actually keywords. They are identifiers that only gain special meaning is a specific context. This means that you can't actually "just" give a colour to these identifiers at any time, you need to know their context.
Luckily, however, this C++11 support has all been done for you in Geany 1.23. Unfortunately Geany 1.23 doesn't do it 100% correct either. That is, if one writes int final = 123; then final will be coloured as a keyword (whereas it actually isn't a keyword). So what they actually did is: they added final as a primary keyword, which isn't exactly correct, but it -sort of- works.
So my advice to you is either download the latest version of Geany from this link or try the following configuration file: (from Geany 1.23)
# For complete documentation of this file, please see Geany's main documentation
[styling=C]
[keywords]
# all items must be in one line
primary=alignas alignof and and_eq asm auto bitand bitor bool break case catch char char16_t char32_t class compl const const_cast constexpr continue decltype default delete do double dynamic_cast else enum explicit export extern false final float for friend goto if inline int int8_t int16_t int32_t int64_t long mutable namespace new noexcept not not_eq nullptr operator or or_eq override private protected ptrdiff_t public register reinterpret_cast return short signed sizeof size_t static static_assert static_cast struct switch template this thread_local throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while xor xor_eq
secondary=
# these are the Doxygen keywords
docComment=a addindex addtogroup anchor arg attention author authors b brief bug c callergraph callgraph category cite class code cond copybrief copydetails copydoc copyright date def defgroup deprecated details dir dontinclude dot dotfile e else elseif em endcode endcond enddot endhtmlonly endif endinternal endlatexonly endlink endmanonly endmsc endrtfonly endverbatim endxmlonly enum example exception extends file fn headerfile hideinitializer htmlinclude htmlonly if ifnot image implements include includelineno ingroup interface internal invariant latexonly li line link mainpage manonly memberof msc mscfile n name namespace nosubgrouping note overload p package page par paragraph param post pre private privatesection property protected protectedsection protocol public publicsection ref related relatedalso relates relatesalso remark remarks result return returns retval rtfonly sa section see short showinitializer since skip skipline snippet struct subpage subsection subsubsection tableofcontents test throw throws todo tparam typedef union until var verbatim verbinclude version warning weakgroup xmlonly xrefitem
[lexer_properties]
styling.within.preprocessor=1
lexer.cpp.track.preprocessor=0
preprocessor.symbol.$(file.patterns.cpp)=#
preprocessor.start.$(file.patterns.cpp)=if ifdef ifndef
preprocessor.middle.$(file.patterns.cpp)=else elif
preprocessor.end.$(file.patterns.cpp)=endif
[settings]
lexer_filetype=C
# default extension used when saving files
extension=cpp
# the following characters are these which a "word" can contains, see documentation
#wordchars=_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
# single comments, like # in this file
comment_single=//
# multiline comments
comment_open=/*
comment_close=*/
# set to false if a comment character/string should start at column 0 of a line, true uses any
# indentation of the line, e.g. setting to true causes the following on pressing CTRL+d
#command_example();
# setting to false would generate this
# command_example();
# This setting works only for single line comments
comment_use_indent=true
# context action command (please see Geany's main documentation for details)
context_action_cmd=
[indentation]
#width=4
# 0 is spaces, 1 is tabs, 2 is tab & spaces
#type=1
[build_settings]
# %f will be replaced by the complete filename
# %e will be replaced by the filename without extension
# (use only one of it at one time)
compiler=g++ -Wall -c "%f"
linker=g++ -Wall -o "%e" "%f"
run_cmd="./%e"
However, I somehow doubt that the above will work without updating to the next version of Geany, because you said that just adding "final" as a primary keyword didn't work for you.
On the other hand, check out the manual on lexer properties if you still want to manually do this.
I hope this helps.
I've updated my development machine to the just-released 12.04 version of Ubuntu, which apparently gave me a new version of GCC (4.6.3). Now source code that used to compile fine is giving me errors about the compiler-generated assignment operator:
source/local.cpp:1185:59: error: no match for ‘operator=’ in ‘olddata = stype::block_t((*(const oc::json_t*)(& local::database_t::getData(const sdata::uuid_t&, size_t*, sdata::override::type_t)((* & uuid), (& otype), (sdata::override::type_t)1u))), 0)’
source/local.cpp:1185:59: note: candidate is:
source/sdata/block.hpp:13:7: note: sdata::block_t& sdata::block_t::operator=(sdata::block_t&)
source/sdata/block.hpp:13:7: note: no known conversion for argument 1 from ‘sdata::block_t’ to ‘sdata::block_t&’
So far as I can tell, the compiler-generated operator= should have the signature foo& operator=(const foo&), not foo& operator=(foo&). Is this a bug in this version of GCC, or is my understanding wrong? I can't find any references to this on the GCC bug-tracker, and I can't believe that no one else has run into it.
(Google doesn't make searching for terms that contain an equals sign easy, but with patience I found a single reference to this problem here, discussing GCC 4.6.2.)
An example of a string class i did once:
String& String::operator=(const String& other) {
// checking for self-assignment (pointer-compare)
if(this != &other) {
delete[] s_buffer;
s_length = other.Length();
s_buffer = new char[s_length+1];
memcpy(s_buffer,other.c_str(),s_length+1);
}
return *this;
}
I don't know what's correct, but GCC's behavior definitely causes problems. I'm calling it a bug.
Oddly enough, it doesn't seem to happen on every class, only a few, so until I can come up with a simple example, I can't really file a bug-report on it.