This is a small code to calculate prime numbers, compile with gcc (Debian 8.3.0-6) 8.3.0
When I use int64_t p = 0
, it work fine. use int64_t p
, it work error.What’s wrong with this?
The variable p
will be assigned by use scanf
OK with int64_t p = 0
:
gcc t.c && ./a.out
input a prime:3
i:2 < number:3
3 is a prime, again
error with int64_t p
:
gcc t.c && ./a.out
input a prime:3
i:2 < number:3
i:3 < number:3
i:4 < number:3
i:5 < number:3
i:6 < number:3
i:7 < number:3
i:8 < number:3
i:9 < number:3
i:10 < number:3
i:11 < number:3
i:12 < number:3
i:13 < number:3
3 not a prime, again
#include <stdint.h>
#include <stdio.h>
int32_t isPrime(int64_t number)
{
int64_t i = 2;
for(; i < number; i++)
{
printf("i:%d < number:%dn",i, number);
if((number % i) == 0)
return 0;
if ((i * i) >= number)
break;
}
return 1;
}
int32_t main(void)
{
int64_t t = 0;
int64_t p;
//int64_t p = 0;
printf("input a prime:");
do
{
scanf("%d",&p);
getchar();
if (isPrime(p))
printf("%d is a prime, again:", p);
else
printf("%d not a prime, again:", p);
}while(1);
}
2
Answers
You’ve declared
p
as anint64_t
, but%d
meansint
. The conversion specifiers forint64_t
and otherstdint.h
types live ininttypes.h
:Similarly, when printing it (using the correct specifier here would have shown you the problem):
Both of these mistakes are something good compilers should be able to warn you about – for example, clang will do it by default. If you’re using gcc, be sure to compile with at least
gcc -Wall
.Also, checking the return value of
scanf
to make sure it succeeded is a good idea. Exiting otherwise is fine if you don’t want to do any deeper recovery.Finally, the correct return type for
main
isint
, notint32_t
.This (
scanf("%d",&p);
) is the wrong code to readint64_t
. Formally, you needscanf("%" SCNd64, &p)
— and<inttypes.h>
(instead of, or as well as,<stdint.h>
).You would probably get away with
scanf("%lld", &p);
since on most machines,int64_t
is a synonym forlong long
.You should also check that
scanf()
returns1
before using the result.When you initialize
p
, you get the ‘correct’ part ofp
set by thescanf()
call because you’re on a little-endian machine, and the remainder is zero as you want. But doing that invokes undefined behaviour. Anything could happen. It is unportable (it probably won’t do what you want on big-endian machines), and completely unreliable because it is undefined behaviour.