Why missing terminating " character is a warning? [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
When, for example, we compile the following code:
printf("hello);
we get a warning then an error about the missing " character. In my opinion, warnings inform us about a code that can be compiled but whose behaviour may be probably different from what the developper expects. Therefore my comprehension missed up two things:
Is there a complete code that can be compiled without errors while containing such a portion of code.
If such a code does not exist, why this missing character situation does not give us only an error (not a warning+error).
EDIT (I am doing my best to cope with off-topic votes recommendations):
1. Desired behavior : only one error diagnostic message, there is no need for a warning for the same thing.
Other related issues that do not let me accept the first answer:
2.1 Does printf_s() have the same issue? I tried to enable -c11 option with no success.
2.2 The historical reason to emit the warning does not seem to me to be plausible since why this double message was not used too in similar cases (old accepted constructions being forbidden in new c versions).

In my opinion, warnings inform us about a code that can be compiled
but whose behaviour may be probably different from what the developper
expects. Therefore my comprehension missed up two things:
Your opinion is irrelevant here, and neither the C standard nor the C++ standard distinguish different categories of diagnostic messages. That many compilers in fact do distinguish is an historically-based convention, albeit a widely observed one. What ultimately matters is what your compiler means by such a distinction (if indeed it makes one). On the other hand, and fortunately for you, GCC does adopt a convention similar to what you describe, as documented in its manual:
Errors report problems that make it impossible to compile your program. [...].
Warnings report other unusual conditions in your code that may indicate a problem, although compilation can (and does) proceed. [...]
(GCC 7.2 manual, section 13.9; the same or similar text appears also in earlier versions of the manual, back to at least v.4.)
Note well that the documentation frames the meaning of a warning slightly differently than you do: a GCC warning signals that compilation can proceed, but there is no assurance that it can complete successfully. If indeed it ultimately cannot then I would expect GCC, pursuant to its documentation, to also issue an error diagnostic. That is exactly what I observe with this test program, whether compiling as C or as C++:
#include <stdio.h>
int main(void) {
printf("hello);
}
I really think you are making far too much of the fact that GCC emits a warning in addition to an error in this case. That's an implementation quirk of no particular significance.
Is there a complete code that can be compiled without errors while containing such a portion of code.
It depends on exactly what you mean by that. Trivially, I could prefix the erroneous line in the above program with // to turn it into a comment, and that would make it perfectly valid C and C++ source. There are manifold other ways I could add to the given source without removing anything to make it valid -- some of them would even produce a program in which a printf() call is in fact performed.
I suppose that what you really want to know is whether there is code that would elicit the warning from GCC but not the corresponding error. To the best of my knowledge, modern GCC does not afford such code, but historically, GCC did allow it as an extension, in the form of embedded, unescaped newlines in string literals:
printf("hello);
Goodbye");
That behavior was already deprecated in GCC 3.2, and it was removed as early as GCC 4 (current is 7.2).
If such a code does not exist, why this missing character situation does not give us only an error (not a warning+error).
We can only guess, but it seems plausible that it derives from the historical existence of the language extension described above. And again, you are making far too much of this. GCC emits two diagnostics about the same problem -- so what? The ultimate purpose of the diagnostics is to help you figure out what is or may be wrong with your code, and the diagnostics GCC emits in this case do that job just fine.

Your compiler probably issues errors when it detects the program is ill-formed, and describes the immediate reason the program failed to be well formed at the location it happened.
This is often useless, because the mistake could have been many lines away.
It also issues warnings that are guesses (often educated guesses) what actually caused your problem. Maybe you forgot a ; on a previous line, failed to close a { or a (. The warning is not "this token is the point of error", but rather "this is where it all went wrong".
In reality, the C++ standard itself does not distinguish between warnings and errors; they are both diagnostics. It mandates some things cause diagnostics, and does not bar compilers from issuing additional diagnostics. Compilers are even free to compile ill formed programs with a warning.
I would expect an error for "newline in string", then a warning pointing at the open quote.

Related

Making `too many arguments in call to function` an error in Clang [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am trying to make the compiler warning warning: too many arguments in call to 'IF' an error (where IF is a function).
I am having trouble configuring clang, as I cannot figure out the actual name of the warning.
I tried the following:
clang -Werror=too-many-arguments main.c
warning: unknown warning option '-Werror=too-many-arguments'; did you mean '-Werror=unknown-argument'?
[-Wunknown-warning-option]
But that just produces the warning above.
With
clang -Werror main.c
The warning does become an error, but I am trying to make only this specific warning an error.
How do I find the name of this compiler warning so I can promote it to a compiler error?
Thanks.
I checked the current sources in Subversion and found this: test/Misc/warning-flags.c in the Clang sources list warn_call_wrong_number_of_arguments (the internal code for this warning), which means that that it is expected that this warning has no separate -W flag. I'm sure the Clang developers would accept a patch which introduces an explicit name for this option.
But until that, -Werror is your only option.
-Werror is turning all warnings into errors. You could turn off all warnings except for that particular one you are interested in, but that is wrong on so many levels, I mention it only for academic reasons.
You might also consider getting a good lint, such as Gimpel's FlexeLint product. This is a lint with completely configurable warnings, errors and informational messages.
This does not directly answer your question, but I believe I can provide a better solution than what you're looking for.
This:
void test () {
printf("test\n");
}
is an old-style non-prototype function definition. As a definition, it specifies that the function has no parameters, but as a declaration, it does not specify the number and types of any expected arguments. Given this definition, a call that incorrectly passes an argument, like test("test") or test(42), is not a constraint violation and does not require a diagnostic, even though such a call has undefined behavior if it's evaluated.
clang is going above and beyond the language requirements to warn you about the incorrect call. (I'm mildly surprised it does so. gcc, for example, does not.)
This kind of thing is exactly why prototypes were added to the language back in 1989. As you mention in the question, you can define the function like this:
void test(void) {
printf("test\n");
}
Given that this definition is visible, a conforming compiler must diagnose any attempt to call this function incorrectly with one or more arguments.
The solution to your problem is not to coax the compiler into diagnosing a problem that the language doesn't require it to diagnose. It's to fix the code. There is very rarely a good reason not to use prototypes for all function declarations and definitions.
Old-style declarations and definitions are obsolescent, but they're still legal even in the 2011 version of ISO C. (I personally consider this unfortunate.)
(You say you don't want to specify void as a parameter, but you haven't explained why.)

C standard prohibition on warnings by default

Seeing yet another question the answer to which would have been obvious had the questioner compiled with -Wall got me thinking.
Is there a 'C standard' based reason why -Wall cannot be enabled by default by the compiler?
As far as I know none of the major compilers do this (and certainly historically none of them did it), and I'd like to know whether this is adherence to the standard, or some other reason (inertia, back compatibility or whatever). Speculating as to the other reason is probably off-topic (opinion based), but I think asking whether a standard requires this behaviour is on-topic (factual).
Quoted from N1570 Annex I:
1 An implementation may generate warnings in many situations, none of
which are specified as part of this International Standard.
This implies that warnings are non-compulsory to compilers, so I don't think there would be any "C standard" based reasons.
Is there a 'C standard' based reason why -Wall cannot be enabled by default by the compiler?
I think that the answer to that is that no standard-based reason. The behavior of compiler switches is outside the scope of a language standard.
Beyond that, a compiler is (generally speaking) not required to produce diagnostics for things that are not specified to be compilation errors, so requiring such diagnostics be output "by default" is nonsensical.
And to be clear, these general statements apply in the case of the C language.
Besides the reason mentioned above, that the standard does not have specifications on warnings, make Wall default would be more a obstacle for many people because there are warnings that you actually don't want to turn on from time to time, such as warnings on unused variables/functions etc.
If you want to make it "by default", you can alias the compiler of your choice, take gcc as example, add following in your bashrc:
alias gcc="gcc -Wall"

Are there any categories to characterize warnings?

My empirical assumption of what compilers warn about in C-Code was actually that they warn the kind of behaving which is implementation defined, or in cases where they detect an construct causing undefined behavior, which they support nevertheless (if they detect and wouldn't they'd throw an error over just warning).
After I had an discussion about this the final proof that I was wrong was this:
#include <whatever_this_needs.h>
int main()
{
int i = 50;
return 0;
}
The compiler obvious warned about i was declared but never used.
I wasn't thinking about this kinds of warning anymore, since I was seeing them more as kind of a tool.... an information.
While I would strictly dissociate this kind of warning from something that warns me about causing inportability or droping significance without explicit cast, it is still something that can cause confusion by compiler optimizations.
So I'm now interested: Are there any categorizations of warning types?
If no standards about it are existing, what are the categories, GCC groups their warnings in?
What I noticed so far (empirical again):
Warnings about:
implementation- / un- defined behaving
unnecessary code (targeted for optimization)
breaking of optional standards (i.e. MISRA or POSIX)
But especially the 2nd point bothers me, since there are constructs (i.e. strict aliasing rules) where optimization can even result in unpredicted runtime behaving, while most cases it just cuts away code that isn't used anyway.
So are my points correct? And what (additional) official categories are there you can 'typecast' warnings in, what are their characteristics, and what is their impact?
Warnings are beyond the scope of the C standard, so there are no requirements or specification for how they should behave. The C standard is only concerned about diagnostics, as in diagnostic messages from the compiler to the programmer. The standard doesn't split those up in errors and warnings.
However, all compilers out there use errors to indicate direct violations of the C standard: syntax errors and similar. They use warnings to point out things beyond what is required by the C standard.
In almost every case, a warning simply means "oh by the way, you have a bug here".
Regarding GCC (see this), it just categories warnings in:
Things that are direct violations against the C standard but valid as non-standard GNU extensions (-pedantic)
"A handful of warnings" (-Wall). Enable all warnings, except some...
"A few warnings more" (-Wextra)
Plus numerous individual warnings with no category.
There's no obvious logic behind the system.
Note that GCC, being filled to the brim with non-standard extensions, have decided just to give warnings instead of errors for some C standard violations. So always compile with -pedantic-errors if you care about standard compliance.
Regarding implementation-defined behavior: C contains a lot of this, it would get very tedious if you would get a warning for every such case ("warning: two's complement int used"...). There's no relation between implementation-defined behavior and compiler warnings.
Regarding any case of undefined behavior, the compiler is often unable to detect it, since the definition of UB is runtime behavior beyond the scope of the standard. Therefore the responsibility to know about and avoid UB lies on the programmer.

Make tolower as static

I need to make the standard library function tolower static instead of "public' scope.
I am compiling with MISRA C:2004, using IAR Embedded Workbench compiler. The compiler is declaring tolower as inline:
inline
int tolower(int _C)
{
return isupper(_C) ? (_C + ('A' - 'a')) : _C;
}
I am getting the following error from the compiler:
Error[Li013]: the symbol "tolower" in RS232_Server.o is public but
is only needed by code in the same module - all declarations at
file scope should be static where possible (MISRA C 2004 Rule 8.10)
Here are my suggested solutions:
Use tolower in another module, in a dummy circumstance, so that it
is needed by more than one module.
Implement the functionality without using tolower. This is an embedded system.
Add a "STATIC" macro, defined as empty by default, but can be
defined to static before the ctype.h header file is included.
I'm looking for a solution to the MISRA linker error. I would prefer to make the tolower function static only for the RS232_Server translation unit (If I make tolower static in the standard header file, it may affect other future projects.)
Edit 1:
Compiler is IAR Embedded Workbench 6.30 for ARM processor.
I'm using an ARM7TDMI processor in 32-bit mode (not Thumb mode).
The tolower function is used with a debug port.
Edit 2:
I'm also getting the error for _LocaleC_isupper and _LocaleC_tolower
Solution:
I notified the vendor of the issue according as recommended by Michael Burr.
I decided not to rewrite the library routine because of localization
issues.
I implemented a function pointer in the main.c file as suggested by
gbulmer; however this will be commented incredibly because it should
be removed after IAR resolves their issue.
I'd suggest that you disable this particular MISRA check (you should be able to do that just for the RS232_Server translation unit) rather than use the one of the workarounds you suggest. In my opinion the utility of rule 8.10 is pretty minimal, and jumping through the kinds of hoops in the suggested workarounds seems more likely to introduce a higher risk than just disabling the rule. Keep in mind that the point of MISRA is to make C code less likely to have bugs.
Note that MISRA recognizes that "in some instances it may be necessary to deviate from the rules" and there is a documented "Deviation procedure" (section 4.3.2 in MISRA-C 2004).
If you won't or can't disable the rule for whatever reason, in my opinion you should probably just reimplement tolower()'s functionality in your own function, especially if you don't have to deal with locale support. It may also be worthwhile to open a support incident with IAR. You can prod them with rule 3.6 says that "All libraries used in production code shall be written to comply with [MISRA-C]".
Who sells the MISRA linker? It seems to have an insane bug.
Can you work around it by taking its address int (*foo)(int) = tolower;at file scope?
Edit: My rationale is:
a. that is the stupidest thing I've seen this decade, so it may be a bug, but
b. pushing it towards an edge case (a symbol having its name exported via a global) might shut it up.
For that to be correct behaviour, i.e. not a bug, it would have to be a MISRA error to include any library function once, like initialise_system_timer, initialise_watchdog_timer, ... , which just hurts my head.
Edit: Another thought. Again based on an assumption that this is an edge-case error.
Theory: Maybe the compiler is doing both the inline, and generating an implementation of the function. Then the function is (of course) not being called. So the linker rules are seeing that un-called function.
GNU has options to prevent in-lining.
Can you do the same for that use of tolower? Does that change the error? You could do a test by
#define inline /* nothing */
before including ctype.h, then undef the macro.
The other test is to define:
#define inline static inline
before including ctype.h, which is the version of inline I expect.
EDIT2:
I think there is a bug which should be reported. I would imagine IAR have a workaround. I'd take their advice.
After a nights sleep, I strongly suspect the problem is inline int tolower() rather than static inline int tolower or int tolower, because it makes most sense. Having a public function which is not called does seem to be the symptoms of a bug in a program.
Even with documentation, all the coding approaches have downsides.
I strongly support the OP, I would not change a standard header file. I think there are several reasons. For example, a future upgrade of the tool chain (which comes with a new set of headers) breaks an old app if it ever gets maintained. Or simply building the application on a different machine gives an error, merging two apparently correct applications may give an error, ... . Nothing good is likely to come of that. -100
Use #define ... to make the error go away. I do not like using macros to change standard libraries. This seems like the seeds of a long-term bad idea. If in future another part of the program uses another function with a similar problem, the application of the 'fix' gets worse. Some inexperienced developer might get the job of maintaining the code, and 'learns' wrapping strange pieces of #define trickery around #include is 'normal' practice. It becomes company 'practice' to wrap #include <ctype.h> in weird macro workarounds, which remains years after it was fixed. -20
Use a command line compiler option to switch off inlining. If this works, and the semantics are correct, i.e. including the header and using the function in two source files does not lead to a multiple defined function, then okay. I would expect it leads to an error, but it is worth confirming as part of the bug report. It lays a frustrating trap for someone else, who comes along in the future. If a different inline standard library function is used, and for some reason a person has to look at the generated code it won't be included either. They might go a bit crazy wondering why inline is not honoured. I conjecture the reason they are looking at generated code is because performance is critical. In my experience, people would spend a lot of time looking at code, baffled before looking at the build script for a program which works. If suppressing inline is used as a fix, I do feel it is better to do it everywhere than for one file. At least the semantics are consistent and the high-level comment or documentation might get noticed. Anyone using the build scripts as a 'quick check' will get consistent behaviour which might cause them to look at the documentation. -1 (no-inline everywhere) -3 (no-inline on one file)
Use tolower in a bogus way in a second source file. This has the small benefit that the build system is not 'infected' with extra compiler options. Also it is a small file which will give the opportunity to explain the error being worked around. I do not like this much but I like it more than the fiddling with standard headers. My current concern is it might not work. It might include two copies which the linker can't resolve. I do like it is better than the weird 'take its address and see if the linker shuts up` (which I do think is an interesting way to test the edge cases). -2
Code your own tolower. I don't understand the wider context of the application. My reaction is not to code replacements for library functions because I am concerned about testing (and the unit tests which introduce even more code) and long term maintenance. I am even more nervous with character I/O because the application might need to become capable of handling a wider character set, for example UTF-8 encoding, and a user-defined tolower will tend to get out of synch. It does sound like a very specific application (debugging to a port), so I could cope. I don't like writing extra code to work around things which look like bugs, especially if it is commercial software. -5
Can you convert the error to a warning without losing all of the other checking? I still feel it is a bug in the toolchain, so I'd prefer it to be a warning, rather than silence so that there is a hook for the incident and some documentation, and there is less chance of another error creeping in. Otherwise go with switching off the error. +1 (Warning) 0 (Error)
Switching the error off seems to lose the 'corporate awareness' that (IMHO) IAR owes you an explanation, and longer term fix, but it seems much better than messing with the build system, writing macro-nastiness to futz with standard libraries, or writing your own code which increases your costs.
It may just be me, but I dislike writing code to work around a deficiency in a commercial product. It feels like this is where the vendor should be pleased to have the opportunity to justify its license cost. I remember Microsoft charged us for incidents, but if the problem was proven to be theirs, the incident and fix were free. The right thing to do seems to be give them a chance to earn the money. Products will have bugs, so silently working around it without giving them a chance to fix it seems less helpful too.
First of all, MISRA-C:2004 does not allow inline nor C99. Upcoming MISRA 2012 will allow it. If you try to run C99 or non-standard code through a MISRA-C:2004 static analyser, all bets are off. The MISRA checker should give you an error for the inline keyword.
I believe a MISRA-C compliant version of the code would look like:
static uint8_t tolower(uint8_t ch)
{
return (uint8_t)(isupper(ch) ? (uint8_t)((uint8_t)(ch + 'A') - 'a') :
ch);
}
Some comments on this: MISRA encourages char type for character literals, but at the same time warns against using the plain char type, as it has implementation-defined signedness. Therefore I use uint8_t instead. I believe it is plain dumb to assume that there exist ASCII tables with negative indices.
(_C + ('A' - 'a')) is most certainly not MISRA-compliant, as MISRA regards it, it contains two implicit type promotions. MISRA regards character literals as char, rather than int, like the C standard.
Also, you have to typecast to underlying type after each expression. And because the ?: operator contains implicit type promotions, you must typecast the result of it to underlying type as well.
Since this turned out to be quite an unreadable mess, the best idea is to forget all about ?: entirely and rewrite the function. At the same time we can get rid of the unnecessary reliance on signed calculations.
static uint8_t tolower (uint8_t ch)
{
if(isupper(ch))
{
ch = (uint8_t)(ch - 'A');
ch = (uint8_t)(ch + 'a');
}
return ch;
}

Handling null pointers on AIX with GCC C

We have a code written in C that sometimes doesn’t handle zero pointers very well.
The code was originally written on Solaris and such pointers cause a segmentation fault. Not ideal but better than ploughing on.
Our experience is that if you read from a null pointer on AIX you get 0. If you use the xlc compiler you can add an option -qcheck=all to trap these pointers. But we use gcc (and want to continue using that compiler). Does gcc provide such an option?
Does gcc provide such an option?
I'm sheepishly volunteering the answer no, it doesn't. Although I can't cite the absence of information regarding gcc and runtime NULL checks.
The problem you're tackling is that you're trying to make undefined behavior a little more defined in a program that's poorly-written.
I recommend that you bite the bullet and either switch to xlc or manually add NULL checks to the code until the bad behavior has been found and removed.
Consider:
Making a macro to null-check a pointer
Adding that macro after pointer assignments
Adding that macro to the entry point of functions that accept pointers
As bugs are removed, you can begin to remove these checks.
Please do us all a favor and add proper NULL checks to your code. Not only will you have a slight gain in performance by checking for NULL only when needed, rather than having the compiler perform the check everywhere, but your code will be more portable to other platforms.
And let's not mention the fact that you will be more likely to print a proper error message rather than have the compiler drop some incomprehensible stack dump/source code location/error code that will not help your users at all.
AIX uses the concept of a NULL page. Essentially, NULL (i.e. virtual address 0x0) is mapped to a location that contains a whole bunch of zeros. This allows string manipulation code e.t.c. to continue despite encountering a NULL pointer.
This is contrary to most other Unix-like systems, but it is not in violation of the C standard, which considers dereferencing NULL an undefined operation. In my opinion, though, this is woefully broken: it takes an application that would crash violently and turns it into one that ignores programming errors silently, potentially producing totally incorrect results.
As far as I know, GCC has no options to work around fundamentally broken code. Even historically supported patterns, such as writable string literals, have been slowly phased out in newer GCC versions.
There might be some support when using memory debugging options such as -fmudflap, but I don't really know - in any case you should not use debugging code in production systems, especially for forcing broken code to work.
Bottom line: I don't think that you can avoid adding explicit NULL checks.
Unfortunately we now come to the basic question: Where should the NULL checks be added?. I suppose having the compiler add such checks indiscriminately would help, provided that you add an explicit check when you discover an issue.
Unfortunately, there is no Valgrind support for AIX. If you have the cash, you might want to have a look at IBM Rational Purify Plus for AIX - it might catch such errors.
It might also be possible to use xlc on a testing system and gcc for everything else, but unfortunately they are not fully compatible.

Resources