1

I have a little bit strange situation. I am compiling on some device. If I compile in Release mode, e.g.

makeCore projectname release exe

All is fine. If I compile in debug mode:

makeCore projectname debug exe

I get following warning:

src/administration.c: In function 'SetIp':
src/administration.c:1409: warning: implicit declaration of function 'InputIp'

Q: Does this mean in the release mode it is safe to use my application?

Why is this behaviour? What to do? I am using the binary compiled in release mode, should I be worried?

Edit: Should I maybe first check out which C standard this compiler conforms to, if it is pre C89 then I should not worry because it is not undefined behaviour right?

Edit2: My ultimate question is if I am trigerring undefined behaviour and how to check whether I am or not trigerring undefined behaviour? I am not sure whether my compiler implements C89 or C90 etc.. Maybe I should ask vendors whether it is undefined behaviour what I did above?

UPDATE:

This is function signature:

s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);

This is how it is called:

s32 res = InputIp(someconstant, u8pointer, otherconstant, otheru8pointer, integer1, integer2);

final question: Since I get this warning in the first place, can I be sure I am using compiler which uses C89? Otherwise it would be error? Am I right?

  • 4
    What exactly is `Release mode` and `debug mode` in `C`? [Hint: You're missing tags] – Sourav Ghosh Jun 17 '15 at 12:04
  • Maybe compiler warnings are turned on only in debug mode. Check your build settings! – Klas Lindbäck Jun 17 '15 at 12:04
  • @KlasLindbäck: Please see my updated question –  Jun 17 '15 at 12:07
  • The only course of action you should consider is investigating *why* `InputIp` is not declared in the debug build (and/or why it is not called in the release build) and then fix the problem once you have located it. – M.M Jun 17 '15 at 12:26
  • @MattMcNabb: This isn't so easy for me to check it is a complex makefile I have no clue about; fixing is OK but this software has been written I think to many devices already –  Jun 17 '15 at 12:32
  • @MattMcNabb: Maybe for this compiler it is not UB? Maybe I should ask vendors anyway? –  Jun 17 '15 at 12:32
  • Assuming `s32` is "signed 32-bit" and `int` on your platform is the same, _and_ your calls (which you haven't shown) wouldn't need coercion to the types listed above, then you're probably OK for existing binaries. You should still add that line either to a header file or near the top of affected source files so that in future the compiler can either make the necessary coercions or tell you when it can't. – TripeHound Jun 17 '15 at 13:03
  • @MattMcNabb: Please see updated question –  Jun 17 '15 at 13:05
  • @user70012 change the source file giving the warning so that it `#include`s the header where you found that definition. (Or if the header is included but the definition is disabled via `#ifdef`s then investigate which ifdefs are causing it) – M.M Jun 17 '15 at 13:40
  • @MattMcNabb: See my reasoning. I get warning as I said in the question. So, what can I deduce from it? Do I deduce that it is C89? Yes? (because if it was later C it would be error?) If yes then I provided function signature and how I use it, and there is where I need your (and maybe others) help if I am on the safe side or not? –  Jun 17 '15 at 13:55

4 Answers4

1

There are a couple of possible reasons why you get a difference.

  1. Lower compiler warning level in release build.

This is the most probable reason.

  1. Conditional code.

Something like this could be the cause:

`#ifndef DEBUG`

`#include "ip.h"`

`#endif`

Note that implicit declaration is a warning you should take seriously as it can hide bugs. I suggest that you add forward declarations where needed.

Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • so you even say it maybe in release mode that file maybe included - which I double more likely warnings are disabled –  Jun 17 '15 at 12:33
  • You should add a forward declaration. If the function is used only in that file, add it early in the `.c` file, or re-order the functions so that the call is after the definition. Otherwise you should include the `.h` file where it is declared. – Klas Lindbäck Jun 17 '15 at 12:43
  • I know how to fix the warning! I was interested if fixing the warning was *necessary* or not?! I remembered in C89 it was OK I was wrong? –  Jun 17 '15 at 12:47
  • It is ok in c89 insofar that it doesn't invoke undefined behaviour provided you provide correct arguments in the function call. If you provide incorrect arguments you invoke undefined behaviour and you get no additional compiler warning about it. – Klas Lindbäck Jun 17 '15 at 13:16
  • Please see my update there I have added signature and how I use it. So if I am calling it correctly I can ask vendors if compiler uses C89 or not and be on the safe side if the compiler does use C89? –  Jun 17 '15 at 13:17
  • Since it is a warning the project is compiling with `-std=c89` (for `gcc` this is the default). In later standards it is regarded as an error. See for example this answer: http://stackoverflow.com/a/9182835/646887 If you for some reason cannot change the code, then it should be safe to leave it. At least for now. – Klas Lindbäck Jun 17 '15 at 13:45
  • Lindback: That is my reasoning also - see I get warning as I said in the question. So, what can I deduce from it? Do I deduce that it is C89? Yes? If yes then I provided function signature and how I use it, and there is where I need your (and maybe others) help if I am on the safe side or not? –  Jun 17 '15 at 13:53
0

You should not rely on implicit declarations, but if InputIp is defined as int InputIp(); you should be fine.

Community
  • 1
  • 1
Peter Petrik
  • 9,701
  • 5
  • 41
  • 65
0

In C89, if the function is prototyped like this (and this prototype is visible at the point of the function body, or the function body uses the same prototype):

s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);

and assuming u8 is an 8-bit type, then calling this function without a prototype in scope causes undefined behaviour.

The rule in this situation (calling prototyped function without a prototype in scope) is that all arguments and return value must remain unchanged under the default argument promotions. Link to related thread

Those promotions, which are the same ones applied to arguments matching ... in variadic functions, are:

  • Any integral type of lower rank than int is promoted to int
  • float is promoted to double
  • All other types remain unchanged

So, the u8 would be changed to int by the default argument promotions.

In C99 calling a function without a declaration in scope is ill-formed.


I strongly recommend fixing the code so that the function is called with a prototype in scope.

Community
  • 1
  • 1
M.M
  • 138,810
  • 21
  • 208
  • 365
  • I was told before I can fix that issue also by including this in one of the header files I am already including: `extern s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);`? do you think this will be enough to solve the problem? thank you. –  Jun 17 '15 at 14:18
  • @user70012 So long as that exactly matches the actual function body, that would fix it. However that is a bad way to code; what should happen is that both the file with the function body, and this file giving the error, include the same header with that line. (the `extern` is redundant, function definitions default to extern) – M.M Jun 17 '15 at 14:20
  • "So long as that exactly matches the actual function body, that would fix it" What do you mean? Isn't the function signature I posted above in comment to you and the one I mentioned in question same? thanks –  Jun 17 '15 at 14:22
  • @user70012 yes , I said that in case you made a transcription error or something. If you do make a little error then you will just get undefined behaviour with no warnings that will be difficult to debug at runtime. – M.M Jun 17 '15 at 14:29
  • You mean I made typo in variable names? I think that should not matter? But types, maybe? more effort must be made to have tools which detect UB IMO –  Jun 17 '15 at 14:31
  • @user70012 there already is one: the compiler. I've already said several times how to use your compiler to prevent UB in this case. But you seem intent on not doing it. – M.M Jun 17 '15 at 14:35
  • Compiler does not detect all undefined behaviour isn't it?? Why I am intent? I told you as device manufacturers told me I plan to put: extern s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy); in one of the headers I already included; ps sometimes it can be also compiler doesn't strictly enforce this implicit declaration rule? –  Jun 17 '15 at 14:38
  • @user70012 that would not prevent detection of UB. You must have the SAME header included by both the file with the function body, and the file making the call. Making copies of the prototype is a recipe for disaster in the future. – M.M Jun 17 '15 at 14:41
  • I don't have function body `InputIP` is method implemented be device vendors and solution with extern is something they told me to put it in header which is included by my project(as they told me they are discontinuing that function maybe that's why extern is OK in this case?) –  Jun 17 '15 at 14:43
  • Also one more question, imagine I did that extern, now that I see that function is called like this: `rslt = sdkInput(SDK_DISP_LINE1, headdis, SDK_DISP_LINE5, ip, 2, 60000);` you can see pre-last parameter had to be of type u8(please see the signature), but I passed `2` which is int? Is it UB? Assuming I already did extern ... –  Jun 17 '15 at 14:44
  • @user70012 OK. In that case the preferable solution would be to include a header provided by the vendor that has the prototype already. If you go with your planned fix then you are trusting that the vendor will never change the function. – M.M Jun 17 '15 at 14:45
  • Dear Matt. Vendor gave me header say Tools.h. They told me to put that extern inside the Tools.h. Tools.h I have already included in my project. (Please also answer me final question about passing 2 etc. comment above) –  Jun 17 '15 at 14:46
  • @user70012 If there is a prototype in scope then the call is correct, `2` gets converted to `u8` because of the prototype. If there is no prototype then it doesn't; the function body expects `u8` but the calling code sends `int`. – M.M Jun 17 '15 at 14:47
  • "In that case the preferable solution would be to include a header provided by the vendor that has the prototype already" - apparently they don't have it? they just told me to add that extern like to one of their existing header files which as I mentioned I have included in my project –  Jun 17 '15 at 14:54
  • When you say it is prototyped like this: `"s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);` " how do you know? in my code I only see this: `sdkInput(SDK_DISP_LINE1, headdis, SDK_DISP_LINE5, ip, 2, 60000);` –  Jun 17 '15 at 15:05
  • @user70012 You said in your question that the prototype was `s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);`. What is `sdkInput` ? – M.M Jun 17 '15 at 15:06
  • I meant InputIp no "sdk" before. I got confused now what I said, this: "sdkInput(SDK_DISP_LINE1, headdis, SDK_DISP_LINE5, ip, 2, 60000)" I call in code. But this ""s32 InputIp(s32 line, u8 * text, s32 otherline, u8 *IP, u8 coordx, s32 coordy);" is just from documentation. Apart from this, I know nothing. I was just not sure what you meant under "prototype"? –  Jun 17 '15 at 15:11
  • "prototype" means declaration of function which includes the types of the function parameters inside the `( )` – M.M Jun 17 '15 at 15:12
  • ok so I will proceed with extern way, if I got you right it should be ok? –  Jun 17 '15 at 18:10
-1

Trying to provide punctual answers:

  1. Does this mean in the release mode it is safe to use my application: The warning means the compiler cannot find the InputIp function prototype. No differences in the run-time behavior of your application (caused by this warning) are expected between the two binary flavors. You should fix it by following the suggestion at 3.

  2. Why is this behaviour: It seems that the compiler flags are adjsted in Makefile according to the parameters passed by you to make ...

  3. What to do?: Add the missing function prototype for InputIp and rebuild your application.

  4. I am using the binary compiled in release mode, should I be worried?: There should be no run-time differences triggered by your issue between the app compiled in debug mode and the one compiled in release mode. You should follow the suggestion at 3

  5. Should I maybe first check out which C standard this compiler conforms to: C89/C90 standards have nothing to do with your issue.

Eugeniu Rosca
  • 5,177
  • 16
  • 45
  • I am really bad with make files and flags-I am using existing make file –  Jun 17 '15 at 12:05
  • The question has slightly changed; the answer does not address it as it stands now –  Jun 17 '15 at 12:11
  • Failure to find the prototype *is* a real issue. If the prototype is not found then the compiler assumes a function declaration which returns `int` and has allowable parameters of only a certain few types. If the actual function body does not match this assumption then it causes undefined behaviour. In any case, this would be an easy problem to investigate so there is no excuse for ignoring the warning. – M.M Jun 17 '15 at 12:25
  • @MattMcNabb: This is my point is it undefined behaviour in all versions of C? (It could be my compiler implements C89 - then I am on the safe side?) How should I figure it out, ask the vendors? –  Jun 17 '15 at 12:26
  • @user70012 in C89 it is undefined behaviour if the function body doesn't match as I described in my previous comment. In C99 the code is ill-formed (therefore the whole executable, if any, has UB). There were no standards prior to C89 so it would just be a guess. – M.M Jun 17 '15 at 12:28
  • 1
    @user70012 it will take less time to fix the problem than to wonder about exactly whether it is UB or not – M.M Jun 17 '15 at 12:28
  • @MattMcNabb: So in all versions of C it is UB you say? I remembered in old versions of C this was allowed; btw this is the method `extern s32 InputIp(s32 siDsipLine, u8 * pAsPrompt, s32 siInputLine, u8 *pAsIP, u8 uAlign, s32 siTimeOut);` –  Jun 17 '15 at 12:31
  • @user70012 Forget about whether it's undefined or not. Even if the behaviour _is_ defined, it could be wrong, depending on the actual return-type and parameters of `InputIp()` (and partly on whether you call it with different parameter types from different places). *If* it returns `int` and the parameters of the first use in your source match the actual parameter types, you _may_ be OK (but fragile to future changes in the source), but it's not worth the risk for the sake of copy-pasting one line to create a prototype. – TripeHound Jun 17 '15 at 12:42
  • @TripeHound: I said it might be written to many devices already - the software –  Jun 17 '15 at 12:47
  • @user70012: As others have said, it _might_ be safe if the compiler's assumptions are correct, but might be dangerous if not. If you cannot work out yourself which is the case, edit your question with the signature of the function and a couple of example uses and someone may be able to help. – TripeHound Jun 17 '15 at 12:53
  • @TripeHound: edited-I call it by passing correct parameter, that is unlikely the issue –  Jun 17 '15 at 12:57
  • Signature won't save me anyway if this is later than C89? Or in later versions I would get an error instead of warning? –  Jun 17 '15 at 13:09