cvLoadImage is returning int? - c

According to the OpenCV documentation cvLoadImage must return pointer to IplImage, but it looks like it is returning int.
when I run the below program, i get some warnings which is shown below program
#include "highgui.h"
#include <stdio.h>
int main(int argc, char** argv)
{
IplImage *img = cvLoadImage ("/path/to/file/face.jpg");
if(img != NULL)
printf("%d", img->width);
}
Also I am getting segmentation fault when I run the above code, I am guessing since img is a int so its causing crash when I am trying to access img->width, Warnings when above code is compiled
/usr/local/Cellar/opencv/3.3.0_3/include/opencv2/core/types_c.h:929:13: warning:
implicit declaration of function 'cvRound' is invalid in C99
[-Wimplicit-function-declaration]
ipt.x = cvRound(point.x);
^
main.c:7:21: warning: implicit declaration of function 'cvLoadImage' is invalid
in C99 [-Wimplicit-function-declaration]
IplImage *img = cvLoadImage ("/path/to/file/face.jpg");
^
main.c:7:15: warning: incompatible integer to pointer conversion initializing
'IplImage *' (aka 'struct _IplImage *') with an expression of type 'int'
[-Wint-conversion]
IplImage *img = cvLoadImage ("/path/to/file/face.jpg");
warning says incompatible converstion from int, so I have change the IplImage to int and it worked fine and it ourputs some negative integer value for img
#include "highgui.h"
#include <stdio.h>
int main(int argc, char** argv)
{
printf("%s\n","hello world");
int img = cvLoadImage ("/path/to/file/face.jpg");
printf("%d", img);
}
I get the below warnings for the above program
implicit declaration of function 'cvRound' is invalid in C99
[-Wimplicit-function-declaration]
ipt.x = cvRound(point.x);
^
main.c:7:15: warning: implicit declaration of function 'cvLoadImage' is invalid
in C99 [-Wimplicit-function-declaration]
int img = cvLoadImage ("/path/to/file/face.jpg");
I went sleepless to figure out it, google could not help, is it something to do with OpenCV versions or C versions?, I am using Opencv2 3.3.0, please feel free to ask if any information is required

There's nothing wrong with the first code and should run fine if compiled with g++ instead of gcc.
The second code you're implicitly converting from IplImage* to int which is wrong and will not run.
The warning and errors regarding cvRound() function has to do with OpenCV C API which hasn't been updated in a while and will most likely be removed in a future version. Most of the new OpenCV functionalities are only present in the C++ API.
Other posts which have mentioned errors regarding cvRound() function in the C API:
https://github.com/opencv/opencv/issues/6076
https://github.com/opencv/opencv/issues/8438
https://github.com/opencv/opencv/issues/8658
In the future try to use OpenCV C++ API for best possible results.

Related

Semantic issue - Implicitly declaring library function 'printf' with type 'int (const char *, ...)'

I can't figure out why I'm getting the warning ⚠️
Using Xcode 11.1 the default Xcode compiler MacOS Catalina.
Implicitly declaring library function 'printf' with type 'int (const char *, ...)'
Include the header or explicitly provide a declaration for 'printf'
#include <stdio.h>
int main( int argc, const char* argv[] ){
printf("Hello World\n");
}
The header was included.
Error Screenshot
Something is wrong with the Xcode on the new MacOS Catalina? I'm missing something?
Thanks in advance 😊

C programming segmentation fault for a returned pointer by a function inside another file [duplicate]

This question already has answers here:
Message "warning: implicit declaration of function"
(10 answers)
Closed 6 years ago.
I have this very simple code written in C. They are in two separate files.
myFunction.c
#include <stdlib.h>
int *extFunc() {
int *a = (int *) calloc( 1, sizeof(int) );
*a = 12;
return a;
}
main.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = (int *) extFunc();
int x = *p; // causes segmentation fault !
printf("%d\n", *p); // causes segmentation fault !
}
I compiled it with this command cc myFunction.c main.c and the output is like below
main.c:6:19: warning: implicit declaration of function 'extFunc' is invalid in C99 [-Wimplicit-function-declaration]
int *p = (int *) extFunc();
^
main.c:6:11: warning: cast to 'int *' from smaller integer type 'int' [-Wint-to-pointer-cast]
int *p = (int *) extFunc();
^
2 warnings generated.
and when I run it, it gives Segmentation fault: 11. What am I doing wrong?
I checked the function when it is in the main.c file and it worked. However, I need them to be separate like above.
In my original code there are struct pointers instead of integer pointers. I explained my problem here with a simplified example.
You haven't provided a prototype for extFunc(). Create a header file with:
int *extFunc(void);
and include it in both source files.
Since the compiler can't see a prototype it assumed int as return type for extFunc() which probably truncates the address returned by calloc() on your system (probably 64bit system).
But there's no implicit int rule since C99. Always include prototypes for functions and pay attention to compiler warnings.
The warnings are very important here. Especially the one saying
cast to 'int *' from smaller integer type 'int'
What is happening is that the compiler makes an implicit declaration of the function. One that doesn't return int * but int. On certain platform (most notably 64-bit systems) those are not the same which means the pointer p in your main function is not correct. Dereferencing it will lead to undefined behavior.
You need to add a declaration of your function for it to work:
int *extFunc(void);
int main(void) { ... }
Also note that I have changed the argument type for both your extFunc and for main. This is because in C when you don't explicitly say that a function takes void as argument then it can take any number of unspecified arguments.
Compiling both files is not enough, you need to create a header:
/* myFunction.h */
int *extFunc();
And then, include it in your main file:
#include <stdio.h>
#include <stdlib.h>
#include "myFunction.h" /* here */
int main()
{
...
}
The main cannot see the declaration of the function extFunc, so it's return type default to int.
As types int and int* are not of the same size, the function returns an invalid pointer, which when dereferenced caused a segmentation fault.
You will need to create a header called myFunction.h, which will contain the declaration of the function:
int* extFunc( void );
Include this header in main and also change the definition of extFunc to take no arguments in myFunction.c.

GCC Incompatible pointer type using a typedef

I have some code that compiled fine under GCC 4.8.4. I've recently upgraded my system and now have GCC 5.2.1, and I'm getting a warning about incompatible pointer types. I've extracted the problem to a small example that reproduces the error:
typedef const double ConstSpiceDouble;
void foo(const double (*)[3]);
int main(int argc, char **argv) {
double a[3][3] = {{1,2,3},{1,2,3},{1,2,3}};
foo((ConstSpiceDouble (*)[3])a);
return 0;
}
In the real code, the typedef, the function definition, and the type cast are in a library outside of my control otherwise I would just fix the cast and the function to match. Here's the message I get from the compiler:
$ gcc -Werror -c test.c
test.c: In function ‘main’:
test.c:9:7: error: passing argument 1 of ‘foo’ from incompatible pointer type [-Werror=incompatible-pointer-types]
foo((ConstSpiceDouble (*)[3])a);
^
test.c:4:6: note: expected ‘const double (*)[3]’ but argument is of type ‘const ConstSpiceDouble (*)[3] {aka const double (*)[3]}’
void foo(const double (*)[3]);
^
cc1: all warnings being treated as errors
The note from gcc is especially troubling since it seems to admit that the two types are identical, yet it complains anyway.
The consensus here and elsewhere seems to be that GCC is doing something unexpected with the const and the typedef. I don't know that unexpected necessarily equates to a bug, but that's for the GCC devs to determine.
I have solved my compilation problem by defining a macro for the function call that fixes the non-matching typecast that's inside the library. I generally dislike tinkering with library internals, but the macro allows me to not touch the actual library header and define it in my own code where it can be commented for the future, and test coverage of that code should be a reasonable early warning signal if the underlying library changes in such a way that the macro breaks something down the road.
This isn't so much "solved" as "worked around", but any further insight will likely have to come from the GCC devs.
If you type cast 'a' to be ConstSpiceDouble, GCC is doing something unexpected with the const and the typedef, by which eventually the type becomes 'const const double'. This you can see in the error message "const ConstSpiceDouble", which equates to 'const const double', this does not work.
Solution is to either say 'a' is const double or to say 'a' is ConstSpiceDouble before you parameter 'a' to the foo function
typedef const double ConstSpiceDouble;
void foo(const double (*)[3]);
int main(int argc, char **argv) {
const double a[3][3] = {{1,2,3},{1,2,3},{1,2,3}};
// or ConstSpiceDouble a[3][3] = {{1,2,3},{1,2,3},{1,2,3}};
foo(a);
return 0;
}
The 'const' pre-pending seems to be a new feature in the latest versions of gcc, but of that, I am not sure :(

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.

Why can I assign a string to a pointer to float?

Why is the code below working? Should that be a compilation error (or at least a run-time error)?
#include <stdio.h>
int main(int argc, char** argv){
float *buf = "happy holiday"; // notice the float
printf("content of buf = %s\n",buf); //its working
return 0;
}
I compiled it and got just a warning:
~/Desktop/cTest>gcc -o run run.c
run.c: In function `main':
run.c:4: warning: initialization from incompatible pointer type
You should always compile with -Wall -Werror -Wextra (at a minimum). Then you get this:
cc1: warnings being treated as errors
test.c: In function 'main':
test.c:4: warning: initialization from incompatible pointer type
test.c:5: warning: format '%s' expects type 'char *', but argument 2 has type 'float *'
test.c: At top level:
test.c:3: warning: unused parameter 'argc'
test.c:3: warning: unused parameter 'argv'
It "works" because in practice, there's no difference between a char * and a float * under the hood on your platform. Your code is really no different to:
#include <stdio.h>
int main(int argc, char** argv){
float *buf = (float *)"happy holiday";
printf("content of buf = %s\n",(char *)buf);
return 0;
}
This is well-defined behaviour, unless the alignment requirements of float and char differ, in which case it results in undefined behaviour (see C99, 6.3.2.3 p7).
This program is not strictly conforming, a compiler is required to output a diagnostic and has the right to refuse to compile it. So don't do it.
This is an unfortunate behavior of gcc, and if somebody could get it fixed, we'd all be dealing with a lot less buggy software. Unfortunately there's a lack of will to fix many things like this. Submitting a bug report would not hurt.

Resources