I was exploring typedefs and stumbled upon this program
EDIT: Nearly all the answers were concerned about the warnings it generates. So, I went ahead and removed all the warnings but the question remains the same.
#include<stdio.h>
typedef int int3[3];
int main(){
int a[2][3] = {{1,2,3}, {4,5}};
int3 *p = a;
int *ip = (int *) a;
printf("sizeof:\np: %lu\n(*p+0): %lu\n**p: %lu\nip: %lu\n*ip: %lu\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
printf("---\n");
printf("p: %p\tp+1: %p\n*p: %p\t*p+1: %p\n**p: %d\nip: %p\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
return 0;
}
on one run it shows:
sizeof:
p: 8
(*p+0): 8
**p: 4
ip: 8
*ip: 4
---
p: 0x7ffe36df31b0 p+1: 0x7ffe36df31bc
*p: 0x7ffe36df31b0 *p+1: 0x7ffe36df31b4
**p: 1
ip: 0x7ffe36df31b0
*ip: 1
My question is:
If p and *p are equal
and **p = 1
then why not *p = 1 as well ?
Provided size of pointer = 8 and size of int = 4
Even if taking in account pointer arithmetic, then *p should at least be 0xkk kk kk kk 00 00 00 01
k being any hex number (consider little-endian)
because de-referencing the same address as int should give 1
EDIT:
To make things clearer, consider this table:
+-----------+----------------------+------------------+
|Variable | Value | Address |
| | | |
| | | |
| p | 0x7ffe36df31b0 | |
| | | |
|*p | 0x7ffe36df31b0 | 0x7ffe36df31b0 |
| | | |
|**p | 1 | 0x7ffe36df31b0 |
+-----------+----------------------+------------------+
How can *p and **p have same address but different value ?
First, note that this code in a confusing mish-mash of constraint violations combined with array decay to generate output of questionable usefulness. But I'll try to answer your question as to what's going on, and try using mundane explanations without resorting to citations from the C Standard, as others already have answered in that manner.
How can *p and **p have same address but different value ?
Because p is a pointer to an array.
Given
typedef int int3[3];
int3 *p;
that means *p is a three-dimensional array. Note that
int3 *p = a;
is a constraint violation, as noted elsewhere. You can force that to "work" with a cast, but it's still fundamentally wrong and the code only "gets away" with it because the address of an array is the address of the first element of that array - and your current implementation doesn't differentiate the pointer types in a significant-enough fashion they they're fundamentally incompatible. Pick an implementation where a plain int * is, say, a 32-bit offset value while an array would have as its address both a 32-bit segment and a 32-bit offset value, and the code would likely generate nonsense if it didn't fail utterly. That's why the C Standard requires pointers to be to "compatible types" - because pointers don't have to be compatible at all.
That problem aside, the initialization/assignment on your implementation can seemingly be treated as
int3 *p = ( int3 * ) a;
Since that "works", that means p contains the address of a three-element array of int values. So dereferencing p with *p is the same as a[0], or the first three-element int array in the two-dimensional a array.
So what is *p, then?
It's exactly the same in this case as a[0], an array. And such a bare array reference decays to an address*, and that address is of the same type as a pointer to an element of the array. And the value of that address will be that of the address of the first element of the array.
So *p, which is a three-element array of int, can itself be dereferenced and evaluate to the first element of a[0], or a[0][0]. So **p is the same as a[0][0].
And a[0][0] - or **p - is an int that is initialized with the value of 1.
While *p is a[0] and the address of that first element.
* - A lot of people say an array "decays to a pointer" or "an array is a pointer", but I like "decays to an address" because a pointer can be assigned to but an address simply is - it can't be assigned to itself, just like an array itself can't be assigned to, but the address can be assigned to something else, like a pointer. Note than when an array is passed to a function, the address of the array actually is passed as an actual pointer. The pointer is the function's parameter and that function parameter can be assigned to...
the posted code, when compiled with:
gcc -c -Wall -Wextra -Wconversion -pedantic -std=gnu11
results in the following compiler messages:
gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" (in directory: /home/richard/Documents/forum)
untitled.c: In function ‘main’:
untitled.c:6:15: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *ip = a;
^
untitled.c:7:26: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:38: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:47: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:55: warning: format ‘%d’ expects argument of type ‘int’, but argument 5 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:64: warning: format ‘%d’ expects argument of type ‘int’, but argument 6 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:9:17: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int (*)[3]’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^
untitled.c:9:26: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘int (*)[3]’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^ ~~~
untitled.c:9:34: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘int *’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^
%ls
untitled.c:9:44: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 5 has type ‘int *’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^ ~~~~
%ls
untitled.c:9:61: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 7 has type ‘int *’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^
%ls
Compilation finished successfully.
The compiler finishes up by saying the compilation was successful. That does NOT mean that it is ok to run this code and expect valid results/output.
When you correct the code so it cleanly compiles, then please post a EDIT to your question that contains the modified/corrected code.
gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" (in directory: /home/richard/Documents/forum)
untitled.c: In function ‘main’:
untitled.c:6:15: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
int *ip = a;
^
untitled.c:7:26: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:38: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:47: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:55: warning: format ‘%d’ expects argument of type ‘int’, but argument 5 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:7:64: warning: format ‘%d’ expects argument of type ‘int’, but argument 6 has type ‘long unsigned int’ [-Wformat=]
printf("sizeof:\np: %d\n(*p+0): %d\n**p: %d\nip: %d\n*ip: %d\n",sizeof p, sizeof (*p+0), sizeof **p, sizeof ip, sizeof *ip);
~^
%ld
untitled.c:9:17: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘int (*)[3]’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^
untitled.c:9:26: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 3 has type ‘int (*)[3]’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^ ~~~
untitled.c:9:34: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 4 has type ‘int *’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^
%ls
untitled.c:9:44: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 5 has type ‘int *’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^ ~~~~
%ls
untitled.c:9:61: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 7 has type ‘int *’ [-Wformat=]
printf("p: %x\tp+1: %x\n*p: %x\t*p+1: %x\n**p: %d\nip: %x\n*ip: %d",p,p+1,*p,*p+1,**p,ip,*ip);
~^
%ls
Compilation finished successfully.
What you have here is constraint violation because you are using incompatible pointer types in the following initialization:
int *ip = a;
As per C11 standard section on Pointer declarators
For two pointer types to be compatible, both shall be identically qualified and both shall be pointers to compatible types.
and on Simple assignment/Constraints
the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
The compiler is require to emit a diagnostic in this case which it does:
<source>:8:15: warning: initialization of 'int *' from incompatible pointer type 'int (*)[3]' [-Wincompatible-pointer-types]
int *ip = a;
See Demo
When you compile a program, it is good practice to enable all warnings and treat warnings as errors so as to avoid (as far as possible) this kind of behavior.
I want to use Netgen - a generator for capacitated networks. But I've got two problems:
If I run make then I get the following error:
cc -O -DDIMACS -c -o netgen.o netgen.c
In file included from netgen.c:86:0:
netgen.h:45:6: error: conflicting types for ‘random’
long random(long, long); /* generate random integer in interval */
^
In file included from netgen.h:31:0,
from netgen.c:86:
/usr/include/stdlib.h:321:17: note: previous declaration of ‘random’ was here
extern long int random (void) __THROW;
^
netgen.c: In function ‘main’:
netgen.c:522:11: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘int’ [-Wformat=]
printf("n %ld\n", i + 1);
^
netgen.c:535:11: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘int’ [-Wformat=]
printf("n %ld s\n", i + 1);
^
netgen.c:538:11: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘int’ [-Wformat=]
printf("n %ld t\n", i + 1);
^
netgen.c:550:11: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 2 has type ‘int’ [-Wformat=]
printf("n %ld %ld\n", i + 1, B[i]);
^
netgen.c:553:9: warning: format ‘%ld’ expects argument of type ‘long int’, but argument 4 has type ‘int’ [-Wformat=]
printf("a %ld %ld %ld %ld %ld\n", FROM[i], TO[i], 0, U[i], C[i]);
^
<builtin>: recipe for target 'netgen.o' failed
make: *** [netgen.o] Error 1
I know the conflict is a result of using stdlib.h and random.c - how can I fix this?
The second problem is that I don't know how to use the problem sets (for example problems.8 and problems.40 (see link above))
Thank you in advance!
I'm trying to write an MPI worker in C that will communicate with the MPI master, written in python. The master will send out scatters and gathers, and the C worker should receive those and return variables via gather. The problem is, I'm having trouble successfully writing the worker file.
(The reason the worker is in C is because this code is a skeleton to wrap around preexisting python and C programs.)
Here is the code I've written:
#include <stdio.h>
#include <mpi.h>
MPI_Comm comm;
MPI_Comm_get_parent(&comm);
int myid, world_size, size;
int root = 0;
int* endloop = malloc(sizeof(int));
int nelements1 = 1E3;
int nelements2 = 1E6;
float* input = malloc(sizeof(float) * nelements1);
float output[nelements2];
int randomarray(){
float array[nelements2];
srand(time(NULL));
for( i = 0; i < nelements2; i++ ){
array[i] = rand() % 0 + 1E6;
}
return array;
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_remote_size(comm, &size);
output = randomarray();
MPI_Scatter(endloop, 1, MPI_INT, root, comm);
while ( endloop[0] < 1) {
MPI_Barrier(comm);
MPI_Scatter(input, nelements1, MPI_FLOAT, root, comm);
MPI_Barrier(comm);
MPI_Gather(output, nelements2, MPI_FLOAT, root, comm);
MPI_Scatter(endloop, 1, MPI_INT, root, comm);
}
MPI_Finalize();
And the error output when I attempt to compile is:
maddie#exo:~/code/bart_commloop$ mpicc worker.c -o worker
worker.c:5:21: error: expected declaration specifiers or ‘...’ before ‘&’ token
worker.c:9:16: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
worker.c:9:1: error: initializer element is not constant
worker.c:12:1: error: initializer element is not constant
worker.c:13:7: error: variably modified ‘output’ at file scope
worker.c: In function ‘randomarray’:
worker.c:18:7: error: ‘i’ undeclared (first use in this function)
worker.c:18:7: note: each undeclared identifier is reported only once for each function it appears in
worker.c:19:21: warning: division by zero [-Wdiv-by-zero]
worker.c:22:2: warning: return makes integer from pointer without a cast [enabled by default]
worker.c:22:2: warning: function returns address of local variable [enabled by default]
worker.c:28:8: error: incompatible types when assigning to type ‘float[1]’ from type ‘int’
worker.c:30:1: warning: passing argument 4 of ‘MPI_Scatter’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:30:1: warning: passing argument 5 of ‘MPI_Scatter’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:30:1: error: too few arguments to function ‘MPI_Scatter’
/usr/lib/openmpi/include/mpi.h:1197:20: note: declared here
worker.c:34:2: warning: passing argument 4 of ‘MPI_Scatter’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:34:2: warning: passing argument 5 of ‘MPI_Scatter’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:34:2: error: too few arguments to function ‘MPI_Scatter’
/usr/lib/openmpi/include/mpi.h:1197:20: note: declared here
worker.c:36:2: warning: passing argument 4 of ‘MPI_Gather’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1058:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:36:2: warning: passing argument 5 of ‘MPI_Gather’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1058:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:36:2: error: too few arguments to function ‘MPI_Gather’
/usr/lib/openmpi/include/mpi.h:1058:20: note: declared here
worker.c:37:2: warning: passing argument 4 of ‘MPI_Scatter’ makes pointer from integer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘void *’ but argument is of type ‘int’
worker.c:37:2: warning: passing argument 5 of ‘MPI_Scatter’ makes integer from pointer without a cast [enabled by default]
/usr/lib/openmpi/include/mpi.h:1197:20: note: expected ‘int’ but argument is of type ‘MPI_Comm’
worker.c:37:2: error: too few arguments to function ‘MPI_Scatter’
/usr/lib/openmpi/include/mpi.h:1197:20: note: declared here
worker.c:40:1: error: expected declaration or statement at end of input
The issue seems to be the formatting of my MPI calls, but I'm not sure what to fix there.
Any help would be greatly appreciated. Thank you!
Parser.h
enum { PLUS, MINUS, DIVIDE, MULTIPLY, NUMBER, END } type;
int token;
/* parsing functions */
void parse_token (void);
Parser.c
void get_token (void)
{
token++;
parse_token(); /* LINE 11 */
}
void parse_token (void) /* LINE 14 */
{
if ( strchr ("1234567890.", token) )
type = NUMBER;
else if ( strchr ("+", token) )
type = PLUS;
else if ( strchr ("-", token) )
type = MINUS;
else if ( strchr ("/", token) )
type = DIVIDE;
else if ( strchr ("*",token) )
type = MULTIPLY;
else if ( token == '\0' )
type = END;
else
show_error(strcat("Couldn't parse token : ", token));
}
The Errors
parser.c:14:6: warning: conflicting types for ‘parse_token’ [enabled by default]
parser.c:11:2: note: previous implicit declaration of ‘parse_token’ was here
parser.c: In function ‘parse_token’:
parser.c:16:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:17:3: error: ‘type’ undeclared (first use in this function)
parser.c:17:3: note: each undeclared identifier is reported only once for each function it appears in
parser.c:17:10: error: ‘NUMBER’ undeclared (first use in this function)
parser.c:19:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:20:10: error: ‘PLUS’ undeclared (first use in this function)
parser.c:22:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:23:10: error: ‘MINUS’ undeclared (first use in this function)
parser.c:25:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:26:10: error: ‘DIVIDE’ undeclared (first use in this function)
parser.c:28:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:29:10: error: ‘MULTIPLY’ undeclared (first use in this function)
parser.c:32:10: error: ‘END’ undeclared (first use in this function)
parser.c: In function ‘show_error’:
parser.c:40:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
I'm utterly bamboozled. :(.
Any help?
One you get it to compile (by including the header, as Luchian Grigore said), you'll find that you can't do strcat() on a constant string.
The constant string is allocated in read-only memory, and can't be modified. And even if you could modify it, you would be overwriting other things in memory.
You're not including your header, so there's no way for the translation unit to know about the declarations of type and token.
You need:
#include "Parser.h"
at the beginning of the implementation file.
I have absolutely no idea why it returns 2 for a=2 and b=2..
Any ideas?
#include <stdlib.h>
int main()
{
double a,b,c;
printf("a=");
scanf("%d", &a);
printf("b=");
scanf("%d", &b);
printf("c=");
scanf("%d", &c);
printf("x=%d", a+b);
return 0;
}
The specifier "%d" expects an integer and you are passing the address of a double. Using the wrong specifiers in scanf leads to undefined behavior.
Also, using the wrong specifier in printf is the same thing. Because printf takes a variable number of arguments a + b which is a double can't be converted to an integer.
%d is for reading integers, use %f or %lf for float/double.
printf should use something like %f instead of %d. The same for scanf.
If you want to accept a float input, use scanf (and printf) with the %lf formatting character, not %d (which is for integers).
The behavior of your current program is undefined, since the scanf calls are writing an integer to a float variable. Also, you're missing include <stdio.h> at the top of your program. To catch errors like these, turn on the warnings in your C compiler:
$ gcc so-scanf.c -Wall
so-scanf.c: In function ‘main’:
so-scanf.c:6:5: warning: implicit declaration of function ‘printf’ [-Wimplicit-function-declaration]
so-scanf.c:6:5: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
so-scanf.c:7:5: warning: implicit declaration of function ‘scanf’ [-Wimplicit-function-declaration]
so-scanf.c:7:5: warning: incompatible implicit declaration of built-in function ‘scanf’ [enabled by default]
so-scanf.c:7:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘double *’ [-Wformat]
so-scanf.c:9:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘double *’ [-Wformat]
so-scanf.c:11:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘double *’ [-Wformat]
so-scanf.c:13:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat]