Actually, PC-Lint does support this with warning 786 "String concatenation within initializer." Adding +e786 to your std.lnt or options.lnt turns this warning on.
Actually, PC-Lint does support this with warning 786 "String concatenation within initializer." Adding +e786 to your std.lnt or options.lnt turns this warning on.
Your version expands __LINE__ to get a unique name for the typedef to avoid a warning/error for typedef redefinition. My point is to use 'export' which allows duplicate declarations in C (or 'typedef' which allows duplicate redefinitions in C++) without having to make names unique.
Stefan
g++ didn't like that -- could this be a C thing but not a C++ thing?
-- My liberal friends think I'm a conservative kook. My conservative friends think I'm a liberal kook. Why am I not happy that they have found common ground? Tim Wescott, Communications, Control, Circuits & Software http://www.wescottdesign.com
Apparently so:
Mel.
Using /gcc-3.4.5-20060117-3/ , gcc liked it, g++ didn't.
-- Les Cargill
Well crap. I thought that worked in g++. Been a long time since I did any c++.
Well, it's ugly but to catch the missing comma issue you can always just wrap the strings in parns - ("some string"), The missing comma will trigger a syntax error. You need something so you do not have "aaa" "bbb" construct.
-- Chisolm Republic of Texas
Ain't one dern thing, it's another, innit? :")
I very briefly tried a pass of "extern "C" ... " to delimit it; no joy.
Aye.
-- Les Cargill
There is no run-time cost (i.e., no wasted code or data space) for either the "extern int" or "typedef" style of static assertion macro. However, I personally use a typedef style because although C (and C++) allow duplicate "externs" and allow "extern" within functions as well as at global scope, /I/ do not allow them and I use warnings (-Wredundant-decls -Wnested-externs) to enforce this policy. I am very strict in insisting that "extern" declarations come with the header file for a module to ensure that definitions and declarations are always consistent. (There are some exceptions, such as for accessing linker variables.)
#define STATIC_ASSERT_NAME_(line) STATIC_ASSERT_NAME2_(line) #define STATIC_ASSERT_NAME2_(line) assertion_failed_at_line_##line #define static_assert(claim, warning) \ typedef struct { \ char STATIC_ASSERT_NAME_(__LINE__) [(claim) ? 2 : -2]; \ } STATIC_ASSERT_NAME_(__LINE__)
By using the same name and format for "static_assert" as C++11 (and C11, with the right header), it is easy to omit the macro definitions if you later compile with the newer standards (and thus get nicer error messages).
"extern "C" ..." just causes functions to have C linkage (unmangled names, no exceptions, etc). The code is still C++, not C.
I wonder if there's a free C++ checker that does this check? cppcheck or clang --analyze don't seem to, at least the versions included in Debian Squeeze.
Gnu C++ didn't like me using "sizeof" in a preprocessor statement -- at least, after experimentation I'm pretty sure that's what it was complaining about.
-- My liberal friends think I'm a conservative kook. My conservative friends think I'm a liberal kook. Why am I not happy that they have found common ground? Tim Wescott, Communications, Control, Circuits & Software http://www.wescottdesign.com
One of my few frustrations with the Gnu project is their assertion that "you don't need Lint, the Gnu compiler is more than paranoid enough for that". It mostly pops up at times like these...
Of course, there may be a flag buried in there someplace that could be turned on -- I should look if I find the time.
-- My liberal friends think I'm a conservative kook. My conservative friends think I'm a liberal kook. Why am I not happy that they have found common ground? Tim Wescott, Communications, Control, Circuits & Software http://www.wescottdesign.com
Yep; sizeof isn't valid in #if expressions. The preprocessor doesn't know the sizes of the built-in types of the compiler to which its output is passed (assuming that its output is actually passed to a compiler), and it doesn't interpret any of the declarations or definitions in the source code which it processes (assuming that its input is actually C or C++ source code).
More generally, the preprocessor doesn't understand C or C++. It just happens to have a compatible token syntax (i.e. the rules for what constitutes a preprocessor token are more or less the same as those for a C token), and the syntax of #if expressions is based upon C expression syntax.
Right!
-- Les Cargill
Yes, that's true - you can't do something like
#if sizeof(strings) != 4 * sizeof(const char*) #error Something's wrong! #endif
But as you can see from other posts (including mine), "static assertions" /can/ be used, and can use "sizeof". They give odd error messages, unless you've got C11 or C++11, but that's a minor quibble.
gcc is definitely better than many other compilers I have used, especially when you enable more of the warning flags. In fact, I often use it to check code when I use C on a target that doesn't have a gcc port (I also use gcc to generate makefile dependencies in such cases) - the target of the gcc build doesn't actually matter in such cases. But gcc certainly doesn't cover everything one might want.
To be fair on the gnu folk, however, much of the work of making a "lint" overlaps with work in a compiler - the parsers are the same, and much of the analysis is similar. If there were people willing and able to make a gnu "lint", they would almost certainly be better off working on gcc and adding more warnings - that would give better results for the effort.
It is also worth noting that additional advanced warnings and checks is something that gcc folks are working on. With each new version, there are more "normal" checks available (such as "-Wdouble-promotion" in 4.6, or "-Wsizeof-pointer-memaccess" in 4.8). In addition, now that plugins are supported, there are a number of research-style projects underway, aimed at things like tracking dynamic memory or other resources.
But you don't need to spend time on this one - there is no such flag for gcc at the moment. You can always make a suggestion on the mailing list, of course.
You might try the GPL'd Splint at
Note that Splint is C literate, not C++, so it may be of limited use in some shops. PC-Lint swings both ways.
I spent several days working with splint and finally gave up. It's got very fundamental design issues that make it pretty much usless.
For example, there was no way to get warnings about this:
unsigned char b = 1234;
Without also getting warned about these:
uint8_t i = 1; char c = 'a';
(In both the above cases, you get a warning about an 'int' value being truncated by the assignemnt operation). To make code pass splint w/o warnings, I found I needed typecasts on about 80% of assignments -- the resulting code was completely unreadable.
I posted to the splint mailing list asking about this and some other very basic problems that made it usless for real world code. I was told splint wasn't intended to be useful for finding problems in source code. It was intended to to be useful for studying the mechansims of language parsing, and they weren't interested in fixing any of the problems that made it useless as a development tool outside of academia.
So, I decided that I'd fork it. I spent some time working on splint to try to fix some of the biggest issues, and it was hopeless. The problems were caused by fundamental design choices that couldn't be undone with a reasonable amount of effort.
So I just tweaked gcc's flags and kept going. At $1000, PC-Lint was just too expensive.
-- Grant Edwards grant.b.edwards Yow! My vaseline is at RUNNING... gmail.com
Tim Wescott skrev 2013-04-02 02:01:
Isn't this possible?
const char * const CHealth::_faultStrings[4] = { [MSG0] = "no status message", [MSG1] = "user fault test", [MSG2] = "motor supply over limit", [MSG3] = "motor supply under limit" }; Wont solve the problem, but would make it more visible.
BR Ulf Samuelsson
Yes, the shrouded-source version for the *ix clan is kinda steep, especially if you're mostly working in gcc-land. Over on the Windows side, the executable version is only about $400 and comes in really handy when faced with using multiple compilers for an assortment of embedded processors. Wonder how well it runs under Wine?
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.