I have the following function in my code:
int numberOverflow(int bit_count, int num, int twos) {
int min, max;
if (twos) {
min = (int) -pow(2, bit_count - 1); \\ line 145
max = (int) pow(2, bit_count - 1) - 1;
} else {
min = 0;
max = (int) pow(2, bit_count) - 1; \\ line 149
}
if (num > max && num < min) {
printf("The number %d is too large for it's destination (%d-bit)\n", num, bit_count);
return 1;
} else {
return 0;
}
}
At compile time I get the following warning:
assemble.c: In function ‘numberOverflow’:
assemble.c:145: warning: incompatible implicit declaration of built-in function ‘pow’
assemble.c:149: warning: incompatible implicit declaration of built-in function ‘pow’
I'm at a loss for what is causing this... any ideas?
You need to include math.h
And why exactly do we get this warning?
From the wording of your warnings it looks like you are using gcc? Maybe it is worth to try another compiler, namely clang. This one tells me:
test-pow.c:15:18: warning: implicitly declaring C library function 'pow' with type 'double (double, double)' [-pedantic]
test-pow.c:15:18: note: please include the header <math.h> or explicitly provide a declaration for 'pow'
Related
code to ask user to input base and power and prints result:
#include <stdio.h>
int main()
{
float v;
int power;
printf("Enter value of x:\t");
scanf("%f", &v);
printf("Enter power:\t");
scanf("%d", &power);
v = exp(v, power);
printf("%.2f", v);
}
float exp(float n, int i) {
float base = n;
int power = i;
float result = 1;
while (power != 0)
{
result = result * base;
--power;
}
return result;
}
compiler spits out:
x.c:11:6: error: too many arguments to function ‘exp’
11 | v = exp(v, power);
| ^~~
clearly:
float exp(float n, int i) {
takes two arguments. What's going on here?
It's because your exp function is not known by the compiler yet.
exp is built-in function in C.
The function prototype of exp() is: double exp(double x);
To make your program work, you should put your exp function above main function.
Two things are happening here.
You have not declared or defined exp() before use
Your compiler has a built-in for exp() with a different signature
I am not sure what compiler you are using but I would be surprised if there were not also warnings explaining this. GCC produces:
main.c: In function ‘main’:
main.c:12:11: warning: implicit declaration of function ‘exp’ [-Wimplicit-function-declaration]
v = exp(v, power);
^~~
main.c:12:11: warning: incompatible implicit declaration of built-in function ‘exp’
main.c:12:11: note: include ‘’ or provide a declaration of ‘exp’
main.c:12:11: error: too many arguments to function ‘exp’
main.c: At top level:
main.c:18:9: warning: conflicting types for built-in function ‘exp’
float exp(float n, int i) {
^~~
Providing a prototype solves the problem:
float exp(float n, int i) ;
int main()
{
...
}
However it is probably ill-advised. The standard library function exp() computes e (Euler's number, 2.7182818...) raised to the given power the single argument, so is semantically different that your exp().
Overriding a standard library function in this way is in any case ill advised even if it has the same semantics. I strongly suggest that you use a different name such as power() for example (not pow() - that is also a standard library function).
Why does my code work ? I am calling the function generateNumber before declaring it, and I haven't set a prototype at the beginning of the file, so normally it shouldn't work, should it ?
Here is my code :
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, const char * argv[]) {
int max = 100;
int min = 1;
int mysteryNumber = generateNumber(min, max);
int enteredNumber = min-1;
do{
printf("Enter a number !\n");
scanf("%d", &enteredNumber);
if (enteredNumber > mysteryNumber) {
printf("It's less !");
}else if(enteredNumber < mysteryNumber){
printf("It's more !");
}
}while (enteredNumber != mysteryNumber);
printf("Congratulations, the mystery number was %d \n", mysteryNumber);
return 0;
}
int generateNumber(int min, int max){
srand(time(NULL));
return (rand() % (max - min + 1)) + min;
}
Thanks by advance !
Surprisingly, this is one of the rare cases when it actually should work with old compilers - specifically, with compilers prior to C99. Still, you shouldn't do it: implicit int has been removed in C99, because it makes code fragile.
When a function lacks prototype, older C compilers used to assume that all its arguments match the types of expressions that you pass, and that their return type is int. Your function happens to match this description: you pass two integers, and treat the return value as an int.
You are right it shouldn't work. My gcc (6.1.0) produces:
test.c: In function ‘main’:
test.c:9:25: warning: implicit declaration of function ‘generateNumber’ [-Wimplicit-function-declaration]
int mysteryNumber = generateNumber(min, max);
^~~~~~~~~~~~~~
It "works" because most compilers are permissive of this by providing an implicit function declaration. However, it's not valid in modern C.
Before C99 removed this implicit function declaration from the standard, it was allowed. But it's not valid anymore since C99.
If your compiler doesn't provide warnings for this, try to increase the warning levels.
I have found an example of multi thread programming which help to determine the prime numbers for a given integar n.it will also take number of thread as a input from the user.But the problem is when i try to execute it give me some errors which very hard to solve.Can anyone help?I am newbies at coding so any type of help and advice will be greatly appreciated.
#include <stdio.h>
#include <math.h>
#include <pthread.h> // required for threads usage
#define MAX_N 100000000
#define MAX_THREADS 25
int nthreads, n, prime[MAX_N+1], nextbase; // next sieve multiplier to be used
// lock for the shared variable nextbase
pthread_mutex_t nextbaselock = PTHREAD_MUTEX_INITIALIZER;
// ID structs for the threads
pthread_t id[MAX_THREADS];
// "crosses out" all odd multiples of k
void crossout(int k)
{ int i;
for (i = 3; i*k <= n; i += 2) {
prime[i*k] = 0;
}
}
// each thread runs this routine
void *worker(int tn) // tn is the thread number (0,1,...)
{ int lim,base,
work = 0; // amount of work done by this thread
// no need to check multipliers bigger than sqrt(n)
lim = sqrt(n);
do {
pthread_mutex_lock(&nextbaselock);
base = nextbase;
nextbase += 2;
// unlock the lock
pthread_mutex_unlock(&nextbaselock);
if (base <= lim) {
// don't bother crossing out if base known composite
if (prime[base]) {
crossout(base);
work++; // log work done by this thread
}
}
else return work;
} while (1);
}
main(int argc, char **argv)
{ int nprimes, // number of primes found
i,work;
n = atoi(argv[1]);
nthreads = atoi(argv[2]);
for (i = 3; i <= n; i++) {
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
nextbase = 3;
// get threads started
for (i = 0; i < nthreads; i++) {
pthread_create(&id[i],NULL,worker,i);
}
for (i = 0; i < nthreads; i++) {
pthread_join(id[i],&work);
printf("%d values of base done\n",work);
}
nprimes = 1;
for (i = 3; i <= n; i++)
if (prime[i]) {
nprimes++;
}
printf("the number of primes found was %d\n",nprimes);
}
I have the following error while compiling:
In function ‘worker’:
Primes.c:67:12: warning: return makes pointer from integer without a cast [enabled by default]
else return work;
^
Primes.c: In function ‘main’:
Primes.c:88:7: warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(int)’
extern int pthread_create (pthread_t *__restrict __newthread,
^
Primes.c:88:7: warning: passing argument 4 of ‘pthread_create’ makes pointer from integer without a cast [enabled by default]
pthread_create(&id[i],NULL,worker,i);
^
In file included from Primes.c:15:0:
/usr/include/pthread.h:244:12: note: expected ‘void * __restrict__’ but argument is of type ‘int’
using: gcc -c -Wall -Wextra -Wconversion -std=gnu99 %f
where %f is the name of the file being compiled
The compiler output the following messages.
I added some commentary for each message that should point you to how to fix the problem.
compiler warning message:
:28:14: warning: conversion to 'int' from 'double' may alter its' value [-Wconversion]
lim = sqrt(n);
The function: sqrt() returns a 'double' but 'lim' is declared a 'int'
Suggest: cast the returned value to 'int'
lim = (int)sqrt(n);
compiler warning message:
:43:12: warning: return makes pointer from integer without a cast [enbled by default]
else return work;
the return type from the worker() function is void*
always exit the worker() function by:
pthread_exit( &work );
compiler warning message:
:24:18: warning: unused parameter 'tn' [-Wunused-parameter]
means the parameter 'tn' is not used. fix this by inserting in that function the line:
(void)tn;
compiler warning message:
47:1: warning: return type defaults to 'int' [enabled by default]
The signature of the main() function is not correct. without using the environment parameter, (almost never used), there are only 2 valid main() signatures and one optional signature.
use the correct signature for what your program needs.
int main( void )
int main( int argc, char *argv[] )
int main() // optional signature
compiler warning message:
50:4: warning: implicit declaration of function 'atoi' [-Wimplicit-function-declaration]
means the header file: stdlib.h has not been #include'd suggest inserting at top of file:
#include <stdlib.h>
compiler warning message:
61:7: warning: passing argument 3 of 'pthread_create' from incompatible pointer type [enabled by default]
means the third parameter to the function: pthread_create() was not a void pointer. suggest:
pthread_create(&id[i],NULL,worker,(void*)&i);
compiler warning message:
67:7: warning: passing argument 2 of 'pthread_join' from incompatible pointer type [enabled by default]
means the variable 'work' should be declared, in file global space, not in the thread function, as:
void * work;
there are other compiler warning messages output, but the above will eliminate them.
I.E. always start with the first compiler message, fix that, then re-compile. then fix the new first message.
Most of the problems with the syntax of the code could have been avoided by paying attention to the man pages for the system functions that were called in the posted code.
Note: the crossout() functions' logic is not correct. the code needs to start at k+k, continue until k<=n and step by k+=k I.E.
for( int k=i+i; k<(n+1); k+=k )
the code seems to be trying to implement a eratosthenes sieve for prime numbers google for the details.
unless your required to use threads, don't, they will just slow things down due to all the context swapping, etc.
this code logic:
for (i = 3; i <= n; i++)
{
if (i%2 == 0) prime[i] = 0;
else prime[i] = 1;
}
seems to be wrong, for one thing, the array prime[] will be initially all 0 because it is in the file global space. As far as I can tell, that code block is not needed at all.
because the work variable will be in the file global space, suggest an array of
void* work[ nthreads ];
then have the thread function: worker() actually use the passed parameter to select which of the entries in the array to be updating.
After reading Structure and Interpretation of Computer Programs (SICP) I decided to find a way to implement some of these functional programming techniques using C. I tried to write a program that makes a pair whose first argument is a name of the function and second arg is any function that takes one arg and returns one arg. Using implementation below I was expecting to see
an output like:
fact(7) = 5040
fib(7) = 13
but instead I am getting
fact(7) = 5040
fib(7) = 0
along with warnings
$ cc map.c
map.c: In function ‘main’:
map.c:41:17: warning: assignment from incompatible pointer type [enabled by default]
maps[0].f_ptr = &fact;
^
map.c:43:17: warning: assignment from incompatible pointer type [enabled by default]
maps[1].f_ptr = &fib;
^
map.c:47:7: warning: passing argument 1 of ‘maps[i].f_ptr’ makes pointer from integer without a cast [enabled by default]
ans = (int) maps[i].f_ptr((int) num);
^
map.c:47:7: note: expected ‘void *’ but argument is of type ‘int’
map.c:47:13: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
ans = (int) maps[i].f_ptr((int) num);
^
map.c:52:7: warning: passing argument 1 of ‘maps[i].f_ptr’ makes pointer from integer without a cast [enabled by default]
ans2 = (int) maps[i].f_ptr((int) num);
^
map.c:52:7: note: expected ‘void *’ but argument is of type ‘int’
map.c:52:14: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
ans2 = (int) maps[i].f_ptr((int) num);
during compilation. Looking at the code I don't see the problem but then again I haven't used C in quite some time. Is there a better way to implement such a construct and why is fib(7) printing a 0 instead of 13?
Here's my code:
struct Map
{
char* name;
void* (*f_ptr)(void*);
};
int fact(int a) {
if (a == 0)
return 0;
if (a == 1)
return 1;
return a * fact (a-1);
}
int fib(int a) {
if (a == 0)
return 0;
if (a == 1)
return 1;
return fib(a-1) + fib(a-2);
}
int findFunc (char* str, struct Map map)
{
if (map.name == str)
return 1;
return 0;
}
int main()
{
int i = 0;
int ans = 0;
int ans2 = 0;
int num = 7;
struct Map maps[2];
maps[0].name = "fact";
maps[0].f_ptr = &fact;
maps[1].name = "fib";
maps[1].f_ptr = &fib;
for (i; i < (sizeof(maps)/sizeof(maps[0])); i++) {
if (findFunc("fact", maps[i]))
ans = (int) maps[i].f_ptr((int) num);
}
for (i; i < (sizeof(maps)/sizeof(maps[0])); i++) {
if (findFunc("fib", maps[i]))
ans2 = (int) maps[i].f_ptr((int) num);
}
printf("fact(%d) = %d\n", num, ans);
printf("fib(%d) = %d", num, ans2);
return 0;
}
String comparisons
This is not how you do string comparison in C.
if (map.name == str)
This is how you do string comparison in C.
if (0 == strcmp(map.name, str))
Because strings in C are just pointers to characters, map.name == str checks if map.name and str are identical pointers (point to the same block of memory), not whether what they point to is the same.
for loops
Your code is probably reporting fib(7) = 0 because it's failing to find fib. One possible culprit is the string comparison issue I mentioned. However, your for loop syntax is also odd:
for (i; i < (sizeof(maps)/sizeof(maps[0])); i++) {
You don't set i to anything, so this means, "Starting from wherever i happens to be, do the following..."
To loop over all of maps, use this:
for (i = 0; i < (sizeof(maps)/sizeof(maps[0])); i++) {
type warnings
As #alk said in a comment, the reason you're getting all of those warnings is because you've declared a function type of void* (*f_ptr)(void*);, even though your functions are int (*)(int). If you want to keep using void* to allow different types, and you're careful enough with your types to make this work, then you can add casts to silence the warnings.
maps[0].f_ptr = (void *(*)(void*)) &fact;
ans2 = (int) maps[i].f_ptr((void*) num);
Etc.
Better implementations?
A "real" implementation of mapping functions to names would use a hash table, instead of linearly searching for matching names. Implementing a hash table in C would add complexity and may not be worth it for this exercise.
but instead I am getting
[...]
fib(7) = 0
The code misses to initialise i to 0 for the 2nd for-loop.
I am trying to generate some numbers with the rand() function like below:
int main()
{
int i=0
for(i=0;i<20;i++)
{
printf("%f\n",rand_md());
}
return 0;
}
float rand_md()
{
return (float)rand()/(RAND_MAX+1.0);
}
But when I run gcc rand.c, I get the error like below:
rand.c: In function ‘main’:
rand.c:21: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’
rand.c: At top level:
rand.c:36: error: conflicting types for ‘rand_md’
rand.c:21: error: previous implicit declaration of ‘rand_md’ was here
What's wrong with my code?
Best Regards,
When you use a function without declaring it first, C will assume it returns an int. To fix this, you have to declare the method signature for rand_md before you call it in main().
Add something like this before main or in a header file:
float rand_md();
double rand_md()
{
return (double )rand()/(RAND_MAX+1.0);
}
Now, rand_md returns a double instead of a float.
Also, since you haven't included it in your post, you should throw in a function prototype before main(). You also forgot to add a semicolon to int i = 0. The corrected code looks like this:
double rand_md();
int main()
{
int i=0;
for(i=0;i<20;i++)
{
printf("%f\n",rand_md());
}
return 0;
}
double rand_md()
{
return (double )rand()/(RAND_MAX+1.0);
}
You can use random(largest size of number) for this purpose.