C Language function called with few arguments, but not error? [duplicate] - c

This question already has answers here:
Why does a function with no parameters (compared to the actual function definition) compile?
(11 answers)
Closed 8 years ago.
In the following C code, function printr called only with one parameter, But all compiled with no warning on GCC and VS.
I am confused why this is OK? Thanks!
#include <stdlib.h>
#include <stdio.h>
int printr(i, j){
printf("The first parameter %d\n", i);
printf("The second parameter %d\n", j);
return 0;
}
int main(){
printr(3);
return 0;
}

Gcc does warn you:
$ gcc -Wextra y.c
y.c: In function ‘printr’:
y.c:4: warning: type of ‘i’ defaults to ‘int’
y.c:4: warning: type of ‘j’ defaults to ‘int’
And once you've fixed those it will warn
y.c: In function ‘main’:
y.c:11: error: too few arguments to function ‘printr’

You defined printr() by using old-fashion function definition syntax, therefore compiler cannot do some syntactic check. You should define it like this:
int printr(int i, int j) {
By the way, with -Wextra, gcc will give warnings about your definition.

Related

Why still compile successfully and got a.out after warning: implicit declaration of function? [duplicate]

This question already has answers here:
Implicit function declarations and linkage
(4 answers)
Closed 2 years ago.
Is it necessary to declare a variable before using it if the compilation works anyway ?
/* hello-world.c */
#include <stdio.h>
int main(void) {
printf("Hello World!\n");
printf("1 + 2 is: %d\n", sum(1, 2));
return 0;
}
/* sum.c */
int sum(int a, int b) {
return a + b;
}
I compile these code with gcc hello-world.c sum.c and clang hello-world.c sum.c,
both got a warning: implicit declaration of function 'sum' but compiled the a.out.
Is there any case proving it's absolutely necessary to declare before using in C?
(edit: Here, i mean the function prototype, if there is any confusion)
"proving" with C is done by the C Standard, not by observation of compilers. Because the standard leaves a lot of things up to compiler discretion .
This program was valid in C89 but is not valid in C99 and later (in which undeclared identifiers cannot be used in expressions).
What the compiler chooses to do with non-compliant programs is up to that compiler, except that some violations (including this one) must result in a diagnostic being printed. Perhaps your compiler opts to print the diagnostic and then go on to behave like C89 .
The classical case is incompatible implicit declaration:
// a.c
int f()
{
return g();
}
// b.c
float g() { return 3.14; }
In this case, it is undefined behavior.

What does this GCC warning mean? [duplicate]

This question already has answers here:
warning: return type defaults to ‘int’ [-Wreturn-type]
(4 answers)
Closed 3 years ago.
Here's the code, straight from 'The C programming Language, Second edition'.
#include <stdio.h>
main ()
{
printf("hello, world\n");
}
Here's the GCC error:
user#root:~/bin$ gcc helloworld.c
helloworld.c:2:1: warning: return type defaults to ‘int’ [-Wimplicit- int]
main ()^~~~
edit: I have just realized that the code did, in fact, compile. I just didn't realize it had overwritten the file for another program I compiled. I've edited the question itself, as I think that has more value. (Originally I asked why this program was not compiling)
You haven't included a return type for main. You probably want to return 0 at the end of it, as that is the standard exit code for no error. Revised your code would be
#include <stdio.h>
int main() {
printf("hello, world\n");
return 0;
}
Try to:
Use int main() since int is return type of main.
EDIT:
In C89, the default return type is int. This default was removed in
C99 and compilers are helpful reminding you that your C-style with no
int before main() is out of date.
That is not an error, it's just a warning. Your code does compile, trying running the resulting binary with ./a.out
GCC is just warning you that you didn't specify a return type for main, and that it will automatically return an integer.
Your main signauture is wrong. You should consider reading this answer to get a C11 standardized signature of the main function :
https://stackoverflow.com/a/2108208/8141369

Why is this pointer variable assignment allowed? [duplicate]

This question already has answers here:
Does this self-assignment do something sensible?
(4 answers)
Compiler not detecting obviously uninitialized variable
(4 answers)
Closed 5 years ago.
While debugging a program of mine, I stumbled upon a weird behaviour of the gcc compiler. I don't know what's the correct title to describe this, but take a look at the code below.
Basically, I had a function which received a void* arg as an argument. It then casted it to a pointer of another type, HTTPRequest*. However, I casted the wrong variable, so the code looked like
void someCallback(void* arg) {
HTTPRequest* req = (HTTPRequest*) req;
FreeRequest(req);
//re-setup request, other stuff..
}
The program then crashed within FreeRequest with a SIGSEGV when it tried to derefrence the pointer. Upon further inspection, req always a had a value of NULL.
It took me a while to realize that the cast I did was just done on the wrong variabe - it should have been
HTTPRequest* req = (HTTPRequest*) arg;
Then it all worked. I was however baffled that gcc allowed me to not only compile this code, but throw no warning whatsoever at this line.
Consider the minimal example
#include <stdlib.h>
#include <stdio.h>
void someFunc(void* arg) {
int* a = (int*) a;
printf("a = %p\n", a);
printf("*a = %d\n", *a);
}
int main() {
int b = 42;
someFunc(&b);
return 0;
}
Compiled with
gcc -Wall -Wextra -Wpedantic -o test -O0 test.c && test.exe
Compiler outputs
test.c: In function 'someFunc':
test.c:7:9: warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int *' [-Wformat=]
printf("a = %p\n", a);
^
test.c:4:21: warning: unused parameter 'arg' [-Wunused-parameter]
void someFunc(void* arg) {
^
And the program outputs:
a = 0061FFCC
*a = 6422500
With optimization at atleast O1 it outputs however:
gcc -Wall -Wextra -pedantic -o test -O1 test.c && test.exe
test.c: In function 'someFunc':
test.c:7:9: warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int *' [-Wformat=]
printf("a = %p\n", a);
^
test.c:4:21: warning: unused parameter 'arg' [-Wunused-parameter]
void someFunc(void* arg) {
^
And outputs
a = 00000000
Then hangs.
So the question is: Why does gcc allow the compilation of expressions of the above form? This is obviously undefined behaviour. Then why are there no warnings about this, even with all warnings enabled?
Why does gcc allow the compilation of expressions of the above form? This is obviously undefined behaviour.
Because the standard allow this. Undefined behavior allow compiler to optimize code write in C. You can read this excellent article from llvm developer.
Then why are there no warnings about this, even with all warnings enabled?
-Wall -Wextra don't active all warning in gcc. clang has -Weverything but, gcc don't have such option.
Compiler are not force to print a warning message for everything. There are few warning that a compiler must print if it want to be standard compliant.
What you do is undefined behavior and this is not mandatory in the standard to print a warning.
clang 4.0.0 has a warning for this -Wuninitialized:
warning: variable 'a' is uninitialized when used within its own initialization [-Wuninitialized]
int* a = (int*) a;
gcc 7.1.1 has a warning for this -Winit-self:
warning: ‘a’ is used uninitialized in this function [-Wuninitialized]
int* a = (int*) a;
Note: Your cast is useless, C will promote any void * to the correct pointer type.

C - Cannot take input after allocating dynamic array [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I need someone to tell me what I am doing wrong over here.
void main(void) {
int *arr,n,i;
printf("Enter the number of elements you want to enter=");
scanf("%d",&n);
arr = (int*)calloc(n,sizeof(int));
if(!arr)
return;
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
for(i=0;i<n;i++)
printf("%d ",arr[i]);
free(arr);
}
This is nothing but a simple program to input the number of items in an array then take the input and print the inputted values. But whenever I go to input the values in the array after taking the number of items from the user, my program CRASHES. I don't understand what I am doing wrong over here. Need some help immediately. Please run the program and see if it also crashes on other systems. I executed the program using an online compiler and strangely there it was running fine. I am using the Visual Studio 2013 command line compiler to execute my program.
Compiling this piece of code with gcc I get:
calloc.c: In function ‘main’:
calloc.c:4:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
calloc.c:5:5: warning: incompatible implicit declaration of built-in function ‘scanf’ [enabled by default]
calloc.c:7:17: warning: incompatible implicit declaration of built-in function ‘calloc’ [enabled by default]
calloc.c:18:5: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
using clang:
calloc.c:1:1: error: 'main' must return 'int'
void main(void) {
^
calloc.c:4:5: warning: implicitly declaring C library function 'printf' with type 'int (const char *, ...)'
printf("Enter the number of elements you want to enter=");
^
calloc.c:4:5: note: please include the header <stdio.h> or explicitly provide a declaration for 'printf'
calloc.c:5:5: warning: implicitly declaring C library function 'scanf' with type 'int (const char *, ...)'
scanf("%d",&n);
^
calloc.c:5:5: note: please include the header <stdio.h> or explicitly provide a declaration for 'scanf'
calloc.c:7:17: warning: implicitly declaring C library function 'calloc' with type 'void *(unsigned long, unsigned long)'
arr = (int*)calloc(n,sizeof(int));
^
calloc.c:7:17: note: please include the header <stdlib.h> or explicitly provide a declaration for 'calloc'
calloc.c:18:5: warning: implicit declaration of function 'free' is invalid in C99 [-Wimplicit-function-declaration]
free(arr);
^
4 warnings and 1 error generated.
As clang kindly pointed out, you need to add
#include <stdlib.h>
#include <stdio.h>
to the top of your code, as you are using functions that are declared within them. The functions you are using are in the standard C library, so the code will still compile but you should expect the unexpected. The reason your program crashes is likely to be that the compiler has made an incorrect assumption about the return type of calloc, as it doesn't have the correct declaration. Many systems will let you get away with this but at the very least they should warn you.
On a side note, please see this discussion on casting the return value of malloc (don't cast it). This advice also applies to calloc.
edit
Here's a minimal example which might shed some light on the issue:
a.c
#include <stdio.h>
int main()
{
printf("%f\n", f());
return 0;
}
b.c
float f()
{
return 4.2;
}
These two files can be compiled separately into object files:
gcc -c a.c # creates a.o
gcc -c b.c # creates b.o
No warnings or errors are generated. Switching to C99 mode causes an "implicit function declaration" warning. Note that at compile-time, the function definition isn't needed. These two object files can be linked:
gcc a.o b.o
Now, the linker finds the definitions of the functions so there is no error but it is already too late. The implicit declaration of f() when a.c was compiled causes the output to be incorrect when the program is run (I get 0.000000).
The same thing has happened here as in your question. The function calloc can be found, so there is no error at link-time. However, an incorrect assumption is made about the type that it returns, so it doesn't behave as expected on your system.

"Implicit declaration" warning

For this code:
int i=0; char **mainp;
for(i=0;i<2;++i)
{
mainp[i]=malloc(sizeof(char)*200);
if(!scanf("%[^#],#",mainp[i]))
break;
if(i<2)
scanf("%[^#],#",mainp[i]);
}
GCC emits the warnings:
warning: implicit declaration of function ‘scanf’
warning: incompatible implicit declaration of built-in function ‘scanf’
warning: ‘mainp’ may be used uninitialized in this function
And I get a segmentation fault at runtime
input:(P>Q),(Q>R),-R#-P
output:
(P>Q),(Q>R),-R
(empt slot)
i expected to give me
(P>Q),(Q>R),-R
-P //where should i fix in my code such that it gives me expected
//output
Problem #1:
warning: ‘mainp’ may be used uninitialized in this function
You need to allocate memory for the array of arrays first.
char **mainp = malloc(sizeof(char*)*2);
Problem #2:
warning: implicit declaration of function ‘scanf’
warning: incompatible implicit declaration of built-in function ‘scanf’
You need to include stdio.h at the top of your file:
#include <stdio.h>
Problem #3: (Not included in your compiling warnings)
Remember to free both the allocated array members and also the array of array address.
gcc expects this line at the beginning of your file:
#include <stdio.h>
and a declaration of mainp like this one:
char *mainp[2];
You shouldn't use functions without declaring them; you used scanf, but at no point in your code is scanf declared. Since it's a standard library function it's declared in one of the standard headers, stdio.h, so you just need to include it:
#include <stdio.h>
Brian's answer is good for the other part

Resources