Book 14: Error Messages Demystified

Previous | Next

One of the things you’ll be doing the most when programming will invariably be trying to track down coding mistakes the compiler complains about. Here’s a list of some common error messages that LLVM (as included with Mac OS X Mountain Lion) will spit out, plus a detailed explanation of the most likely cause of these errors.

As mentioned earlier in the Masters of the Void tutorial, LLVM will valiantly struggle on and try to make sense of your program even when it encounters an error. Many of the errors LLVM will show you will simply be caused by LLVM having misunderstood you on the first error, and then misunderstanding the rest of the program. Thus, the closer you get to the bottom of a list of errors, the less the error messages may make sense. It’s a good idea to keep this in mind when LLVM throws 500 error messages at you. Fix the first error, then compile again. Chances are, half of the subsequent errors will be gone.

Conflicting types … previous implicit declaration

main.c:101:9: Conflicting types for 'GetArgument'
main.c:40:13: Previous implicit declaration is here

or

Warning: Implicit declaration of function 'GetArgument' is invalid in C99

What does it mean? LLVM reads your source files from top to bottom. When it finds a function it doesn’t know about, it usually assumes that it’s a function that returns an int and takes ... as its parameters (use Xcode’s menu command Help -> Documentation and API Reference and type stdarg into the search field for details on ... parameters). This assumption is called an implicit declaration, because LLVM just assumes that’s what you wanted and you were too lazy to write out a declaration. It is also usually a completely wrong guess, though it makes the code compile. When LLVM later encounters your actual function definition, it will notice that your parameters don’t have the type ... and maybe that it also doesn’t return an int and warn you about it in the above fashion.

Solution: To avoid this error, either reorder your functions so the called function is above the function calling it and LLVM has seen the function before it’s first used, or add/include a forward declaration (see the chapter on headers).

If it is not one of your functions, you may have forgotten to #include the header for this function in your program, or you might have mis-spelled its name (pintf, anyone?)


More ‘%’ conversions than data arguments

Warning: More '%' conversions than data arguments

What does it mean? LLVM calls “%d” and similar placeholders in a printf format string “% conversions”. This means that you have e.g. five occurrences of “%s” in your format string, but are only passing four strings after the format string to printf.

Solution: Make sure that you have exactly as many “%s” (or similar placeholder) occurrences in your printf’s first string as you are passing additional values to fill those placeholders.


data argument not used by format string

data argument not used by format string

What does it mean? LLVM calls the actual values you provide to printf to fill placeholders like %d” data arguments. This indicates that you are passing more data than you have placeholders in your format string.

Solution: Make sure that you have exactly as many “%s” (or similar placeholder) occurrences in your printf’s first string as you are passing additional values to fill those placeholders.


using the result of an assignment as a condition without parentheses

using the result of an assignment as a condition without parentheses

What does it mean? You are probably using the assignment operator ‘=’ instead of the comparison operator ‘==’ in the condition of an “if” statement, or of a “while” or “for” loop.

Solution: If you are trying to compare two values, correct this to be the ‘==’ comparison operator. If you really intend to assign that value (a rare but not impossible case), wrap the condition in a second pair of brackets, e.g. “while(( myDevice = GetNextDevice() ))” to indicate that this was really your intention.


expression result unused

expression result unused

or

Warning: Equality comparison result unused

What does it mean? You are probably using the comparison operator ‘==’ instead of the assignment operator ‘=’ on a line of its own. Alternately, you may be using one of the other comparison or mathematical operators without using their result as a parameter or assigning it to a variable, or you may be using ‘+’ instead of ‘+=’, ‘-‘ instead of ‘-=’, etc. In any way, your code does pointless work the way it is now.

Solution: If you are trying to assign a value to a variable, correct this to be the ‘=’ assignment operator. If you are trying to change a variable by adding to it, subtracting from it etc., correct it to the appropriate operator (e.g. ‘+=” instead of ‘+’ or whatever you meant). Or maybe you forgot to write the name of a variable and the assignment operator at the start of the line.


Assigning to … from incompatible type ‘void’

Assigning to 'int' from incompatible type 'void'

What does it mean? C is very picky about its types matching. When you assign a number to a variable, both the variable and the number are for example of type ‘int’. But in this case, the second operand is of type void, and as we know void essentially means ignore me. You shouldn’t be using a value that’s to be ignored in an expression. Since you can’t really declare a variable of type void (how large would a void be, anyway?), it can’t be one of your variables, so what is it? Well, functions that don’t have return values are declared as void. So, very likely, you’ve got a line like the following somewhere in your code:

foo = MyFunction( 123 );

where MyFunction is declared as:

void MyFunction( int n );

Or you have some function like in Chapter 5, where we have:

void GetArgument( bool isLeft, int* vFirstArg );

which returns its value by reference through the address passed as vFirstArg, and you’re calling it like:

vFirstArg = GetArgument(true, &vFirstArg );

Solution: Check the types of all variables and the return types of all functions you’re using in expressions on the line with the error. Very likely you forgot to specify int or float as the return type from a function, or you wanted a different function. In a case like GetArgument() in Chapter 5, the solution would be to simply get rid of the vFirstArg = part, as the &vFirstArg part combined with the code in the function itself already takes care of assigning the value to vFirstArg.


Use of undeclared identifier …

Use of undeclared identifier 'twue'

What does it mean? You are using a word the compiler has never heard of. Apart from a few little things built into the compiler (like if, for, int, void, return and a few others), everything you use in C is actually written in a C source code file provided by the system (or rather, in a “library”). Since the C compiler itself only knows the language, it can’t know where these files are.

Solution: Add a #include statement to tell your compiler about the header file that tells it about the word you are using. Either that’s a header file created by you, or one of the system header files.

Previous | Next

This entry was posted in C Tutorial. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *


*