A conforming C compiler must issue at least one diagnostic for the program in your question.
Your square
function is declared as:
int square(void);
which says it takes no arguments and returns an int
result. You then call it as:
square(i)
which passes one argument. This is a constraint violation, which means that a compiler must issue a diagnostic (which may be either a warning or a fatal error).
You then define it as:
square(a) { /* ... */ }
which is an old-style definition. It says that square
takes an int
argument and returns an int
result (under the obsolete "implicit int
" rule). But that definition is not visible at the point of the call, so the compiler will process the call using only the declaration.
According to Microsoft's documentation, this:
#pragma warning (disable:4996)
disables warnings for "deprecated" functions. It shouldn't apply to anything in your program, so you should still get a warning or fatal error on the incorrect call square(i)
.
Either your compiler is buggy or, more likely, either the code in your question or your description of the compiler's behavior is incorrect.
Please copy-and-paste the exact code from your question and try compiling it. If it really does compile without warnings or errors, you have a serious problem with your compiler or with the way you're using it.
(Of course the declaration, definition, and call to square
should all be consistent, but your question is about why the compiler doesn't diagnose the error, not about how to fix it in your source code.)
As for why you get different output with int
vs. float
, if the declaration and definition of a function are inconsistent, any call results in undefined behavior. When you change the definition to use float
, the generated code is probably passing an int
value that the function incorrectly interprets as a float
value. The result is meaningless.
UPDATE: Now that I've seen your screenshot, it looks like your compiler is doing something I didn't expect. It warns that the declaration int square(void)
has a void parameter list. By itself, that declaration is perfectly valid; it's only a problem because the following definition defines square
with an int
argument. It must have decided to warn about the declaration after it saw the incompatible definition.
The thing that really surprises me is that it doesn't warn about the call square(i)
. That call is consistent with the definition (which follows it), but inconsistent with the declaration (which precedes it).
C is designed to be processed in one pass. The legality of a construct depends on the code that precedes it, not on what follows it.
But the only requirement imposed by the C standard is that the compiler must issue at least one diagnostic. It says nothing about the wording of that diagnostic, nor does it require it to be a fatal error. In this case, the code violates a constraint (because the declaration and definition of square
are incompatible), and in my opinion it should reject the program -- but a warning satisfies the standard's requirements.
Regardless of the decisions made by the authors of the compiler, it did produce several warning messages, and you should not ignore them. It's (perhaps indirectly) pointing out problems with your code, and you should fix those problems. The fact that the compiler warned about your code is sometimes more informative than the actual content of the warnings.