Implicit declaration of function x - c

I'm well aware of function prototypes, this error seems to be a function declaration error, which means I'm really bewildered as to why I'm see this warning and thus error.
It's almost like gcc completely ignores my function prototype. Is this a compiler bug?
In the interest of brevity, I did not declare this function in a separate header file, though it should make no difference.
gcc output:
$ gcc -Wall -std=c99 -pedantic primefactors.c
primefactors.c: In function ‘main’:
primefactors.c:8:5: warning: implicit declaration of function ‘largestprime’ [-Wimplicit-function-declaration]
primefactors.c: At top level:
primefactors.c:12:6: error: conflicting types for ‘largestprime’
primefactors.c:8:20: note: previous implicit declaration of ‘largestprime’ was here
code:
#include <stdio.h>
#include <math.h>
long largetsprime(long);
int main()
{
printf("%d\n", largestprime(600851475143));
return 0;
}
long largestprime(long num)
{
int highest;
int mid = sqrt(num);
for (int i = 2; i < mid; i++) {
if (mid % i == 0) {
if (i % 1 == 0 && i % i == 0)
highest = i;
}
}
return highest;
}

Point-1
You have misspelled largest in function name
long largetsprime(long)
^
s is wrong here
In declaration It should be
long largestprime(long)
^ before t
Point-2
You are using sqrt() library function from math.h, you should compile your program with -lm as:
gcc -Wall -std=c99 -pedantic primefactors.c -lm
Point-3
You are returning int whereas return type of your function is long.
Point-4
One more mistake suggestion in call of printf() you forgot adding suffix for long int.
largestprime(600851475143)
should be:
largestprime(600851475143L)
// ^ added suffix L for long
If you are not aware of suffix L then read: What does the “L” mean at the end of an integer literal?
Thanks to #Eric Postpischil:
point-5: printf() in main() function is printing long type integer whereas you have used %d format specifier to print it:
printf("%d\n", largestprime(600851475143));
^
|
returns long
use %ld instead.
point-6:
if-condition in largest prime function i % 1 == 0 and i % i == 0 are each always true (except the latter is undefined if i is zero) because i % 1 = 0 (every number is divisible by 1).

Typo. The declaration says largeTSprime. Change it to the correct largestprime and it will work.
ProTip #1: use camelCapsOnWordBoundaries or under_scores for readability.
ProTip #2: it's almost never a compiler bug.

You have a typo in the prototype. It should be largestprime instead of largetsprime.

You have a typo in the prototype:
largetsprime != largestprime

Related

How does this code print 404?

I copied this below code from Stack Overflow's 404 Not Found Error Page.
# define v putchar
# define print(x)
main(){v(4+v(v(52)-4));return 0;}/*
#>+++++++4+[>++++++<-]>
++++.----.++++.*/
print(202*2);exit();
#define/*>.#*/exit()
The above code compiles fine and prints 404 on the console. I thought the statement print(202*2); is responsible for printing 404, but I am not right because changing the numbers in this statement also prints 404.
Could somebody help me to understand this code and how it prints 404?
Am posting the compilation output for your reference as there are comments saying this code doesn't compile. The file containing above code is Test.c.
gcc Test.c -o Test
Test.c:3:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main(){v(4+v(v(52)-4));return 0;}/* ^ Test.c: In function ‘main’:
Test.c:1:12: warning: implicit declaration of function ‘putchar’
[-Wimplicit-function-declaration] # define v putchar
^ Test.c:3:8: note: in expansion of macro ‘v’ main(){v(4+v(v(52)-4));return 0;}/*
^ Test.c: At top level: Test.c:6:14: warning: data definition has no type or storage class print(202*2);exit();
^ Test.c:6:14: warning: type defaults to ‘int’ in declaration of ‘exit’ [-Wimplicit-int] Test.c:6:14: warning:
conflicting types for built-in function ‘exit’
./Test
404
Cannot use a meta-question as dupe, so blatantly copying from the MSO answer.
Since this is tagged c and mentioned "compiled", so just extracting the C part of it.
Credits: Mark Rushakoff is the original author of the polyglot.
The C code is fairly easy to read, but even easier if you run it
through a preprocessor:
main(){putchar(4+putchar(putchar(52)-4));return 0;};exit();
Your standard main function is declared there, and exit is also
declared as a function with an implicit return type of int (exit
is effectively ignored).
putchar was used because you don't need any #include to use it;
you give it an integer argument and it puts the corresponding ASCII
character to stdout and returns the same value you gave it. So, we
put 52 (which is 4); then we subtract 4 and output 0; then we add
4 to output 4 again.
Also, a little more elboration, from [Cole Johnson's]
(https://meta.stackoverflow.com/users/1350209/cole-johnson) answer
Disregarding all of that, when we reformat the code a bit, and replace
52 with its ASCII equivalent ('4'), we get:
int main() {
putchar(4 + putchar(putchar('4') - 4));
return 0;
}
As for the putchar declaration, it is defined by the standard to
return it's input, like realloc. First, this program prints a 4,
then takes the ASCII value (52), subtracts 4 (48), prints that
(ASCII 0), adds 4 (52), prints that (4), then finally
terminates. This results in the following output:
404
As for this polyglot being valid C++, unfortunately, it is not as
C++ requires an explicit return type for functions. This program takes advantage of the fact that C requires functions without an
explicit return type to be int.
# define v putchar
this defines v as the putchar() function. It prints a character and returns it.
# define print(x)
this defines print(x) as nothing (so print(202*2) means nothing)
main(){v(4+v(v(52)-4));return 0;}/*
this could be rewritten as:
main()
{
putchar(4 + putchar(putchar(52) - 4));
return 0;
}
it is using ASCII codes to print '4' (code 52), '0' (code 52 - 4 = 38) and again '4', so "404".
That line ends with a /* starting a comment the continues through the next two lines:
#>+++++++4+[>++++++<-]>
++++.----.++++.*/
The line below turns out empty, but it is a bit tricky because exit() is defined as empty AFTER the line itself. That works because the C preprocessor runs BEFORE the compilation.
print(202*2);exit();
The line below defines exit() as empty, used on the line above.
#define/*>.#*/exit()
The code cannot compile on a standard C compiler, such as gcc -std=c11 -pedantic-errors.
1) main must return int on hosted systems.
2) putchar() must have #include <stdio.h>.
3) You can't write semicolons outside functions.
After fixing these beginner-level bugs and removing all superfluous fluff that doesn't do anything but creating compiler errors, we are left with this:
#include <stdio.h>
#define v putchar
int main(){v(4+v(v(52)-4));return 0;}
This revolves around putchar returning the character written:
putchar(4+putchar(putchar(52)-4));
52 is ASCII for '4'. Print 4.
52 - 4 = 48, ASCII for 0. Print 0.
4 + 48 = 52. Again print 4.
And that's it. Very bleak as far as obfuscation attempts go.
Proper, standard-compliant obfuscation would rather look something like this:
#include <stdio.h>
#include <iso646.h>
??=define not_found_404(a,b,c,d,e,f,g,h,i,j)a%:%:b%:%:c%:%:d%:%:e%:%:f(\
(g%:%:h%:%:i%:%:j<::>)<%'$'+d##o%:%:e not "good",g??=??=ompl ??-- -0163l,\
((void)(0xBAD bito##b not "bad"),not "ugly")??>,(g%:%:h%:%:i%:%:j??(??)){\
((c%:%:d%:%:e)- -not "lost") <:??=a??) -??-??- '<',\
((c%:%:d%:%:e)- -not "found") <:??=b??) -??-??- 'B',\
((c%:%:d%:%:e)- -not 0xDEADC0DE) <:??=c??) -??-??- '5',\
((c%:%:d%:%:e)- -6##6##6 xo##b- -6##6##6)%>)
int main()
{
not_found_404(p,r,i,n,t,f,c,h,a,r);
}
you have defined V as putchar() which take ascii code of char to be printed and return ascii value of printed char. execution of your program will start from the main as bellow
first v(52) will print 4 and return 52
second v(52-4) will print 0 (48 is ascii value of 0) and return 48
finally it will call to v(48+4) will print 4 as 52 is ascii value of '4'.

C function returns correct result but no return statement is given, why?

So I've written a function that should return the n'th Fibonnacci number, but I forgot to actually return my result. I did get the " control reaches end of non-void function" warning, but the code executed fine and returned the correct result. Why is that? How does C know that it should return "result"?
int fib (int n);
int main(int argc, char** argv) {
printf("%d", fib(10));
}
int fib (int n){
if (n == 1){
return 1;
}
if (n == 0){
return 0
}
fib(n-2) + fib(n-1)
}
It returned this
55
I've tried to add
int j = n+1
to the last line of the function, and then it actually returned 2, not 256. Is this a bug, or how does c read something like this?
Reaching the end of a non void function without a return statement invokes undefined behavior. Getting the expected result is a form of undefined behavior commonly called luck. By the way, 256 may be what you expected, but it is not correct.
A possible explanation is: the last value computed by the function and stored into the register that would normally contain the return value is the expected result.
Of course you should never rely on this, nor expect it.
This is a good example of the use of compiler warnings: do not ignore them. Always turn on more compiler warnings and fix the code. gcc -Wall -W or clang -Weverything can spot many silly mistakes and save hours of debugging.
Here are some other problems:
you do not include <stdio.h>
you compute an unsigned long long but only return a probably smaller type int
your algorithm computes powers of 2, not Fibonacci numbers.

C prog error: expected expression before int

This is the program:
#include <stdio.h>
#define round(a) ((a-0.5)<int(a))?int(a):int(a+1)
int main() {
double a = 5.2;
int m = round(a);
printf("%d", m); }
and it shows the error: expected expression before 'int'
round is a name reserved by the standard C library so it is undefined behaviour to call your macro that name (even if you don't include math.h).
Your algorithm could be better expressed like this:
#define my_round(a) ( (int)((a) + 0.5) )
which also has the benefit of only evaluating its argument once.
It would be preferable to use an inline function:
inline int my_round(double d)
{
return d + 0.5;
}
Note that both options cause undefined behaviour if a is outside the bounds of INT_MIN, INT_MAX roughly . If it's in a critical environment you should make your inline function check the bounds of d before doing the conversion to int.
This
#define round(a) ((a-0.5)<int(a))?int(a):int(a+1)
Has the brackets in the wron places
Should be
#define round(a) (((int)((a)-0.5))<(a))?(int)(a):(int)(a+1)
The problem is that int(a) is not valid C.
Redefine your macro as follows:
#define round(a) (((a)-0.5)<(int)(a))?(int)(a):(int)(a+1)
Note that I've also added parentheses around a in (a)-0.5.
P.S. What's the reason for making it a macro and not, say, a function?
The error is because of int(a). Syntactically it is wrong. It should be (int)(a).

Inconsistency using printf

I am using Code Block with GNU GCC Compiler. And I am trying this code
int number,temp;
printf("Enter a number :");
scanf("%d",&number);
temp = sqrt(number);
printf("\n%d",sqrt(number)); //print 987388755 -- > wrong result
printf("\n%d",temp); //print 3 -- > write result
return 0;
and in this code there are a result for input value 10 is
987388755
3
what is wrong in this code?
sqrt returns a double:
double sqrt(double x);
You need:
printf("\n%g",sqrt(number));
Using incorrect format specifier in printf() invokes Undefined Behaviour. sqrt() returns double but you use %d.
Change:
printf("\n%d",sqrt(number));
to:
printf("\n%g",sqrt(number));
Note that sqrt() returns a double, not an int - your compiler should be warning you about this, so long as you have warnings enabled. e.g. gcc -Wall ... (and if you don't have warnings enabled, then it's time to start making a habit of it).

Behaviour of printf when printing a %d without supplying variable name

I've just encountered a weird problem, I'm trying to printf an integer variable, but I forgot to specify the variable name, i.e.
printf("%d");
instead of
printf("%d", integerName);
Surprisingly the program compiles, there is output and it is not random. In fact, it happens to be the very integer I wanted to print in the first place, which happens to be m-1.
The errorneous printf statement will consistently output m-1 for as long as the program keeps running... In other words, it's behaving exactly as if the statement reads
printf("%d", m-1);
Anybody knows the reason behind this behaviour? I'm using g++ without any command line options.
#include <iostream>
#define maxN 100
#define ON 1
#define OFF 0
using namespace std;
void clearArray(int* array, int n);
int fillArray(int* array, int m, int n);
int main()
{
int n = -1, i, m;
int array[maxN];
int found;
scanf("%d", &n);
while(n!=0)
{
found=0;
m = 1;
while(found!=1)
{
if(m != 2 && m != 3 && m != 4 && m != 6 && m != 12)
{
clearArray(array, n);
if(fillArray(array, m, n) == 0)
{
found = 1;
}
}
m++;
}
printf("%d\n");
scanf("%d", &n);
}
return 0;
}
void clearArray(int* array, int n)
{
for(int i = 1; i <= n; i++)
array[i] = ON;
}
int fillArray(int* array, int m, int n)
{
int i = 1, j, offCounter = 0, incrementCounter;
while(offCounter != n)
{
if(*(array+i)==ON)
{
*(array+i) = OFF;
offCounter++;
}
else
{
j = 0;
while((*array+i+j)==OFF)
{
j++;
}
*(array+i+j) = OFF;
offCounter++;
}
if(*(array+13) == OFF && offCounter != n) return 1;
if(offCounter ==n) break;
incrementCounter = 0;
while(incrementCounter != m)
{
i++;
if(i > n) i = 1;
if(*(array+i) == ON) incrementCounter++;
}
}
return 0;
}
You say that "surprisingly the program compiles". Actually, it is not surprising at all. C & C++ allow for functions to have variable argument lists. The definition for printf is something like this:
int printf(char*, ...);
The "..." signifies that there are zero or more optional arguments to the function. In fact, one of the main reasons C has optional arguments is to support the printf & scanf family of functions.
C has no special knowledge of the printf function. In your example:
printf("%d");
The compiler doesn't analyse the format string and determine that an integer argument is missing. This is perfectly legal C code. The fact that you are missing an argument is a semantic issue that only appears at runtime. The printf function will assume that you have supplied the argument and go looking for it on the stack. It will pick up whatever happens to be on there. It just happens that in your special case it is printing the right thing, but this is an exception. In general you will get garbage data. This behaviour will vary from compiler to compiler and will also change depending on what compile options you use; if you switch on compiler optimisation you will likely get different results.
As pointed out in one of the comments to my answer, some compilers have "lint" like capabilities that can actually detect erroneous printf/scanf calls. This involves the compiler parsing the format string and determining the number of extra arguments expected. This is very special compiler behaviour and will not detect errors in the general case. i.e. if you write your own "printf_better" function which has the same signature as printf, the compiler will not detect if any arguments are missing.
What happens looks like this.
printf("%d", m);
On most systems the address of the string will get pushed on the stack, and then 'm' as an integer (assuming it's an int/short/char). There is no warning because printf is basically declared as 'int printf(const char *, ...);' - the ... meaning 'anything goes'.
So since 'anything goes' some odd things happen when you put variables there. Any integral type smaller than an int goes as an int - things like that. Sending nothing at all is ok as well.
In the printf implementation (or at least a 'simple' implementation) you will find usage of va_list and va_arg (names sometime differ slightly based on conformance). These are what an implementation uses to walk around the '...' part of the argument list. Problem here is that there is NO type checking. Since there is no type checking, printf will pull random data off the execution stack when it looks at the format string ("%d") and thinks there is supposed to be an 'int' next.
Random shot in the dark would say that the function call you made just before printf possibly passed 'm-1' as it's second parm? That's one of many possibilities - but it would be interesting if this happened to be the case. :)
Good luck.
By the way - most modern compilers (GCC I believe?) have warnings that can be enabled to detect this problem. Lint does as well I believe. Unfortunately I think with VC you need to use the /analyze flag instead of getting for free.
It got an int off the stack.
http://en.wikipedia.org/wiki/X86_calling_conventions
You're peering into the stack. Change the optimizer values, and this may change. Change the order of the declarations your variables (particularly) m. Make m a register variable. Make m a global variable.
You'll see some variations in what happens.
This is similar to the famous buffer overrun hacks that you get when you do simplistic I/O.
While I would highly doubt this would result in a memory violation, the integer you get is undefined garbage.
You found one behavior. It could have been any other behavior, including an invalid memory access.

Resources