mathgl and single letter variable names in C - c

I am trying to implement MATHGL graphs in QT windows.
Compilation of the appropriate libraries went fine, and example provided compiles and runs without error.
When trying to build sample code, something strange happens when I try to add a single letter named variable regardless of its type (int, double, others).
This simple code illustrates the problem
#include <mgl2/mgl_cf.h>
int sample(HMGL gr, void *p)
{
int I; /* REMOVE THIS LINE OR RENAME VARIABLE (TWO LETTERS) FOR COMPILATION */
mgl_rotate(gr,40.,60.,0.);
mgl_box(gr);
return 0;
}
int main(int argc,char **argv)
{
HMGL gr;
gr = mgl_create_graph_qt(sample,"MathGL examples",0,0);
return mgl_qt_run();
}
MATHGL version is 2.1.3.1, compiler is gcc 4.7.2, libraries used: -lpng15 -lz -lm -lstdc++ -lmgl -lmgl-qt
Error in compilation reads:
file.c: In function ‘sample’:
file.c:5:7: error: expected identifier or ‘(’ before ‘__extension__’
file.c: In function ‘main’:
file.c:16:6: warning: assignment makes pointer from integer without a cast [enabled by default]
I do not know what I'm missing here, can you please help me??
thanks in advance!!

Your problem: I is most likely a macro for the imaginary unit (as described here).
Use a different variable name (and avoid all-caps variable names in general).

Related

Odd C global char type declaration error message in both GCC and Clang?

Question: Is it me, or do both GCC and Clang have not quite correct error messages when assessing particular global char declarations in C?
---And a particular note regarding a similar question is that I'm looking for clarification regarding why the char declaration is getting this reaction. There are related questions, yes, but all I saw there was int declarations.
$ gcc --version
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0
$ clang --version
clang version 10.0.0-4ubuntu1
Consider the following C code, able.c:
#include <stdio.h>
char able;
able = 'X';
int main(void)
{
printf("%c", able);
}
A first note is that yes, combining the declaration and the initialization of able is much more efficient. However, when run through GCC and Clang, the error messages that turn up seem to me to be, basically, incorrect messages:
$ clang -Weverything able.c
able.c:5:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
able = 'X';
^
able.c:5:1: error: redefinition of 'able' with a different type: 'int' vs 'char'
able.c:3:6: note: previous definition is here
char able;
^
able.c:3:6: warning: no previous extern declaration for non-static variable 'able' [-Wmissing-variable-declarations]
char able;
^
able.c:3:1: note: declare 'static' if the variable is not intended to be used outside of this translation unit
char able;
^
2 warnings and 1 error generated.
$ gcc -Wall -Wextra -Wpedantic able.c
able.c:5:1: warning: data definition has no type or storage class
5 | able = 'X';
| ^~~~
able.c:5:1: warning: type defaults to ‘int’ in declaration of ‘able’ [-Wimplicit-int]
able.c:5:1: error: conflicting types for ‘able’
able.c:3:6: note: previous declaration of ‘able’ was here
3 | char able;
| ^~~~
Both sets of messages complain about a missing type specifier, except that the type specifier---char---is indeed right there. When the declaration and initialization messages are combined in that spot, above/before the main function, the program compiles. When the pair of messages are placed in the main function, even without being combined, the program also compiles.
So the char able; statement is perfectly fine, so why those error messages?
You can't do
char able;
able='X';
on file scope.
You can only do it in one line, not split, like you are used in functions.
The C compiler thinks:
char able; //Declare a variable of type char with name able.
able = 'X'; //Assign the ASCII-value of 'X' to a variable called able of type `int`.
The int is implicit because of backwards compatibility with really old versions. (Because of this you will sometimes see main() instead of int main(void)).
Furthermore, you have now two variables of the same name. This leads to this error:
redefinition of 'able' with a different type: 'int' vs 'char'
Edit:
Here an excerpt from the C specification (Draft):
Annex A, A.1 (Lexical grammar), A.2.4 (External Definition)
translation-unit: //Essentially a file
external-declaration
translation-unit external-declaration
external-declaration:
function-definition
declaration //The interesting one
declaration: //A 2.2 (Declarations)
declaration-specifiers init-declarator-list[opt];//init-declarator-list is optional
static_assert-declaration//Not interesting here
declaration-specifiers:
storage-class-specifier declaration-specifiers[opt]
type-specifier declaration-specifiers[opt]
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiers[opt]
alignment-specifier declaration-specifiers[opt]
As you can see here in the grammar, there is no place on translationunit-base for only an assignment.
The compile gives error as able='X' is never executed by the program. (C program acts sequentially inside the functions only. For global variables only the declaration with/without initialization is considered.
#include <stdio.h>
char able;
able = 'X'; //This statement is never executed
int main(void)
{
printf("%c", able);
}
A similar question can be found at: Why can't I assign values to global variables outside a function in C?
As statements are not allowed in file scope the compiler tries to interpret this statement
able = 'X';
as a declaration. But it does not find a type specifier. So it issues the message
able.c:5:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
able = 'X';
After it inserted the default type specifier int it sees that the name able is declared twice like
char able;
int able = 'X';
where int is the type specifier inserted by the compiler by default.
So the compiler issues the message
able.c:5:1: error: redefinition of 'able' with a different type: 'int' vs 'char'
able.c:3:6: note: previous definition is here
char able;
^
Inside block scope you may place declarations and statements. So this code snippet
char able;
able = 'X';
placed in a function block scope will compile successfully.
From the C Standard (6.8 Statements and blocks)
3 A block allows a set of declarations and statements to be grouped
into one syntactic unit.
able = 'X';
You cant have any code or assignments outside the functions. compiler treats it as new definitions with implicit int type. The assignment has to be in the function body as in the example.
#include <stdio.h>
char able;
void foo()
{
able = 'X';
}
int main(void)
{
foo();
printf("%c", able);
}
https://godbolt.org/z/dea7q7

Why gcc doesn't check implicit declaration of function when re-define malloc() in cmd line (-D)?

Here is my original function (test.c):
#include <stdlib.h>
int main()
{
void *p = malloc(1);
free(p);
return 0;
}
If I re-define malloc in gcc cmd line with -D, gcc compiles it fine. (why it doesn't complain at my_malloc()?)
gcc -c -Wall -D malloc=my_malloc test.c
If I change the malloc name in my code to malloc2:
#include <stdlib.h>
int main()
{
void *p = malloc2(1);
free(p);
return 0;
}
And then re-define it, gcc now finally complains:
$ gcc -c -Wall -D malloc2=my_malloc test.c
test.c: In function ‘main’:
test.c:5:5: warning: implicit declaration of function ‘my_malloc’ [-Wimplicit-function-declaration]
void *p = malloc2(1);
Could someone help me explain why this is happening?
This has to do with how the preprocessor is working.
Assuming you #include <stdlib.h> at the top of your file, the first thing that happens is that this include file is basically imported into your source file. Next, the define passed in to the command line gets processed.
In the first case, this changes not only the call to malloc in your code but also the declaration of malloc imported from stdlib.h. So no implicit declaration. In the second case, the malloc2 call gets changed, but there's no corresponding declaration that gets swapped out as well. So you get the warning.
This is under gcc 4.1.2.
The warning you get in the third case is because you have used a function malloc2() (or my_malloc() in case you use the -Dmalloc2=my_malloc define) without a prototype. In this case, the <stdlib.h> defined prototype doesn't match the define you make in the command line, and you don't get a prototype for it anymore.
As standard behaviour, if you don't include a prototype for a function before it's first use, it defaults to return int and to use an undefined number of parameters. This means that the compiler is assuming you have a int my_malloc(); function defined elsewhere and as you are trying to assign an integer value to a pointer variable, there's something wrong in your code.
If you want the compiler assume your malloc implementation is like the standard library one, just define it with void *malloc(const size_t); before that first use.

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 compilation still work when inverting the main function argument position

Why my C program doesn't work when I declare the main function like this (I inverted the arguments position) :
int main(char * argv, int argc){
}
I compiled it without problem but I got errors when I run it.
Thanks.
Due to the incorrect main() signature, this is not a valid C program.
Try enabling compiler warnings. My compiler tells me about the problem:
$ gcc -Wall test.c
test.c:1:5: warning: first argument of 'main' should be 'int' [-Wmain]
test.c:1:5: warning: second argument of 'main' should be 'char **' [-Wmain]
See What are the valid signatures for C's main() function?
Unlike in C++, functions in C are solely identified by their names, not their arguments. E.g. linker will be pretty happy when it sees a 'main' function.
Nevertheless, there are certain assumptions how main() is called by the operating system resp. the runtime environment. When your parameters are wrong, your program will see unexpected values and might crash.
And btw, you probably will see errors or warnings when you enable diagnostics (e.g. '-Wall -W') when building the program.
This is an incorrect main() signature. You may check the main function.
The parameters argc, argument count, and argv, argument vector,1
respectively give the number and values of the program's command-line
arguments. The names of argc and argv may be any valid identifier in
C, but it is common convention to use these names.
Also check What should main() return in C and C++?

Warning: cast to pointer from integer of different size

I wrote the following code:
struct DVDARRAY
{
int length;
pDVD* dvds;
};
typedef struct DVDARRAY DVDARRAY_t;
//...
int main()
{
int i;
char c;
DVDARRAY_t* dvds;
poDAOproperties props;
props = get_dao_properties();
dvds = (DVDARRAY_t*) DVDDAO_read_raw_filter(props, "id = 1");
printf("title->: %s", dvds->dvds[0]->title);
}
and in another file the following is defined:
DVDARRAY_t* DVDDAO_read_raw_filter(poDAOproperties properties, char* filter)
{
DVDARRAY_t *dvds;
// ...some code...
dvds = malloc(sizeof(DVDARRAY_t));
// ...some code...
return dvds;
}
Now my question: when I try to compile these files I get the following warning:
src/main.c: In Funktion »main«:
src/main.c:80:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
Line 80 of main.c is exactly that line:
dvds = (DVDARRAY_t*) DVDDAO_read_raw_filter(props, "id = 1");
What can I do?
You do not list the file names above so I will just call them main.c and dvd.c.
In main.c, you make a call to the otherwise undeclared function DVDDAO_read_raw_filter. This tells the compiler to assume that the function exists, has an unknown (but fixed) set of arguments, and has a return value of type int.
In dvd.c you define the function DVDDAO_read_raw_filter with fixed (and known) arguments, returning type DVDARRAY_t*. (Presumably you have to repeat the definition of DVDARRAY_t first.)
Note that main.c believes something untrue about DVDDAO_read_raw_filter, namely, that it has return type int. This is causing your compile-time diagnostic. By luck (you can decide for yourself whether this is good or bad luck :-) ) the program runs successfully in spite of this incorrect belief.
To fix the problem, tell main.c about the function before calling it, i.e., declare it. You can also get a more explicit warning from gcc by adding -Wimplicit-function-declaration to your compile-time flags.
In general, it's a good idea to put struct definitions, typedefs, and function declarations into a header file (e.g., dvd.h) and then #include that header in the various C source files that make use of the definitions and declarations. That way the compiler can compare the function declarations against the function definitions, and you need not repeat the contents of structs and the names of typedefs in multiple .c files.
If you are just trying to make things work...
unsigned char *temp;
int number;
temp = someArr[y][x].charAtThisLoc;
number = (int)(size_t)temp;
other solutions didn't work for me.

Resources