Following is the C Code :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int a,b,d;
void Values1()
{
a=a*2;
b=b-5;
}
void Values2(register int c)
{
d+=b-c;
a=a+10;
b*=3;
}
int a,b;
int main()
{
int i=7;
Values2(i);
Values1();
printf("a=%d, b=%d, d=%d\n",a,b,d);
system("pause");
}
It Gives a Compilation Error related to redefinition of 'a' and 'b' in MS Visual C++ 2010.
Please help me in figuring out why this error has occured.
You define a and b in the global scope here:
int a,b,d;
and here
int a,b;
You can not define variables twice.
Your compiler is badly configured. Your program is legal C.
The re-declarations of a and b fall into the category of "tentative definition". A properly configured C compiler, cannot stop compilation because of that.
Why do you have these two lines?
int a,b,d;
int a,b;
You only need to define the variables once. I'd suggest getting rid of the second line.
Some other things you may want to consider in the interests of furthering your skills.
Global variables are usually consider a bad thing. There are better ways to do it which encapsulate information much better, and will reduce the likelihood of problems down the track.
Use meaningful variable names. They only slow down the compiler the tiniest bit and will not affect your running speed, but they make your code so much easier to maintain.
I like to space out expressions to make them more readable as well, like d += b - c; instead of d+=b-c;.
Don't bother with the register keyword, it's a suggestion to the compiler and most modern compilers are far better than developers at figuring out how best to optimise code.
There are two canonical prototypes for main and int main() isn't one of them - use int main (void) if you don't care about program arguments.
On pre-C99 compilers, you should return 0 from main (C99 will return 0 for you if you reach the closing brace of main).
Right after the definition of Values2(), there is the line int a,b; which will conflict with int a,b,d; before Values1(), so you can safely remove the line int a,b;.
Besides, to get good results, you may want to set tha values of a, b and c in the start of the main function to get consistent results.
Related
This question already has answers here:
Difference between int main() and int main(void)?
(10 answers)
Closed 3 years ago.
Preface:
This is probably gonna be marked as a duplicate, and I understand, but I am asking this, because I feel other answers may not be quite as clear. In fact, the closest answers that I have found that make the most sense to me are this one: from 2015 and this one: from 2013, about return 0;
I have very little programming experience--I messed around with Java several years ago, and kinda figured out what I needed to copy and paste to edit the program I was playing with, and I have written a simple program in python, and I played around with Scratch in School. But, I have finally decided to sit down, learn a language, C, and just roll with it.
So, what I would like to ask, is, am I interpreting this right? because, if so, then it can be said there is, for most intents and purposes, no difference between int main(), with no arguments, and int main(void).
Actual Importance:
To summarise my current understanding:
If int main() is used, then you should add at the end return 0;, to signify the programs termination.
Though possible, it is improper to use int main() and not use return 0;, as many compilers may not recognise this.
If int main(void) is used, then it is unnecessary to add return 0;.
In plain English, would this be said as a good, and/or accurate explanation?
Examples:
/*
* Program example using scanf, printf, and int main() with no variable
* This program reads a string from the user
*/
#include <stdio.h>
int main() {
char name[10]; /* number in square brackets is for max characters in name */
printf("Enter name: ");
scanf("%s", name); /* scanf will read input until it sees blank space, then stop */
printf("Hello, %s!\n", name);
return 0;
}
vs.
/*
* Program example using scanf, printf, and int main(void)
* This program reads a string from the user
*/
#include <stdio.h>
int main(void) {
char name[10]; /* number in square brackets is for max characters in name */
printf("Enter name: ");
scanf("%s", name); /* scanf will read input until it sees blank space, then stop */
printf("Hello, %s!\n", name);
}
If int main() is used, then you should add at the end return 0;, to signify the programs termination.
Mostly true. This is good practice, although not strictly necessary, as we'll see.
Though possible, it is improper to use int main() and not use return 0;, as many compilers may not recognise this.
Mostly false. For some time now, and as a special case unique to a function named main(), if you do not supply a return statement, the compiler is required to arrange that main implicitly return 0.
An old compiler may still require the return 0;, and behave badly if it is omitted -- although the malfunction is typically minor. Also a compiler so old as to not comply with this requirement will certainly have many other, more significant compatibility issues to worry about.
If int main(void) is used, then it is unnecessary to add return 0;.
Correct, but misleading. There is no difference whatsoever between int main() and int main(void) in this regard. It is also true (per the above) that if int main() is used, it is unnecessary to add return 0.
The difference is that int main() doesn't specify a prototyped declaration for main. As a definition of the function, the two are equivalent, and define the function in mutually compatible ways. However, int main() introduces less compile-time information into the scope.
In C (unlike C++), main is allowed to recurse. Thus we can consider the following silly program:
int main(void)
{
main(42);
}
because main is declared completely, the main(42) call is a constraint violation, requiring a diagnostic. If we change the program to:
int main()
{
main(42);
}
then the function hasn't changed: it's still one that takes no arguments. But that information is not declared as part of the main identifier's type information, and so the call doesn't require a diagnostic. (If translated and executed, it invokes undefined behavior; but that may happen even if there is a diagnostic.)
This is an old style, before C had function prototype declarations, which were first standardized in 1989's ANSI C and in widespread use before that.
The latest standard allows you to ommit the return 0 statement. As for the protype of main(), there are 3 equally variants:
int main()
int main(void)
int main(int argc, char* argv[])
An empty parameter list in C means that you can pass as many parameters as you want but the function will not care about any of them. Specifying a void parameter list means that you explicitly have to pass no arguments or you will get an error.
While the standard only explicitly accepts versions #2 and #3, version #1 also works because the OS passes the arguments for version #3 and your function will not care about them.
Hope my answer was clear enough.
Since I found this particular documentation on https://www.tutorialspoint.com/c_standard_library/c_function_rand.htm,I have been thinking about this particular line of code srand((unsigned)time(&t));.Whenever I had to generate some stuff,I used srand(time(NULL)) in order not to generate the same stuff everytime I run the program,but when I came across this,I have been wondering :Is there any difference between srand((unsigned)time(&t)) and srand(time(NULL))?Because to me they seem like they do the same thing.Why is a time_t variable used?And why is the adress operator used in srand()?
#include <stdio.h>
#include<stdlib.h>
int main(){
int i,n;
time_t t;
n = 5;
srand((unsigned)time(&t));
for (i = 0; i < n; i++) {
printf("%d\n", rand() % 50);
}
return(0);
}
Yes, it will yield the same result. But the example is badly written.
I would be careful reading Tutorialspoint. It's a site known for bad C code, and many bad habits you see in questions here at SO can be traced to that site. Ok, it's anecdotal evidence, but I did ask a user here why they cast the result of malloc, and they responded that they had learned that on Tutorialspoint. You can actually see (at least) four examples in this short snippet.
They cast the result from the call to time() which is completely unnecessary and just clutters the code.
For some reason they use the variable t, which is completely useless in this example. If you read the documentation for time() you'll see that just passing NULL is perfectly adequate in this example.
Why use the variable n? For this short example it's perfectly ok with a hardcoded value. And when you use variables to avoid hardcoded values, you should declare them const and give them a much more descriptive name than n. (Ok, I realize I was a bit on the edge when writing this. Omitting const isn't that big of a deal, even if it's preferable. And "n" is a common name meaning "number of iterations". And using a variable instead of a hard coded value is in general a good thing. )
Omitted #include<time.h> which would be ok if they also omitted the rest of the includes.
Using int main() instead of int main(void).
For 5, I'd say that in most cases, this does not matter for the main function, but declaring other functions as for example int foo() with empty parenthesis instead of int foo(void) could cause problems, because they mean different things. From the C standard:
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.
Here is a question related to that: What are the semantics of function pointers with empty parentheses in each C standard?
One could also argue about a few other things, but some people would disagree about these.
Why declare i outside the for loop? Declaring it inside have been legal since C99, which is 20 years old.
Why end the function with return 0? Omitting this is also ok since C99. You only need to have a return in main if you want to return something else than 0. Personally, in general I find "it's good practice" as a complete nonsense statement unless there are some good arguments to why it should be good practice.
These are good to remember if your goal is to maintain very old C code in environments where you don't have compilers that supports C99. But how common is that?
So if I got to rewrite the example at tutorialspoint, i'd write it like this:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
srand(time(NULL));
for (int i = 0; i < 5; i++) {
printf("%d\n", rand() % 50);
}
}
Another horrible example can be found here: https://www.tutorialspoint.com/c_standard_library/c_function_gets.htm
The function gets is removed from standard C, because it's very dangerous. Yet, the site does not even mention that.
Also, they teach you to cast the result of malloc https://www.tutorialspoint.com/c_standard_library/c_function_malloc.htm which is completely unnecessary. Read why here: Do I cast the result of malloc?
And although they mention that malloc returns NULL on failure, they don't show in the examples how to properly error check it. Same goes for functions like scanf.
I was creating an int array and making all of its element 0 in C.
Using:
int arr[50],i;
for(i=0;i<50;i++){
arr[i]=0;
}
Which works fine if used inside a function or in main() like:
int main(){
int arr[50],i;
for(i=0;i<50;i++){
arr[i]=0;
}
return 0;
}
But something strange happens if we use the code outside of any function like:
#include <stdio.h>
int arr[50],i;
for(i=0;i<50;i++){
arr[i]=0;
}
int main()
{
printf("Hello World!");
return 0;
}
Gives error on compilation:
error: expected identifier or '(' before 'for'
for(i=0;i<50;i++){
^
So by that, is it that grammar of C doesn't support looping outside of a function?
If no, then why is this happening?
You're defining an anonymous block, which is not allowed (it needs to be predeceded by a function definition, otherwise, the compiler will never know when it will have to execute it).
In C, every line of code but variable declaration/initialization must lie within a function.
The only things that may appear at the top level of a translation unit are declarations or function definitions.
What you have here is confusion in programming paradigm. If I'm not mistaken (I may be! Just a guess...) you are familiar with python programming, which is written in an imperative paradigm. This means that within a file each line is read and performed top down, one by one. In such a paradigm your proposed code outside of a function would operate just fine.
Since you are writing in the C language you are writing in a procedural paradigm (or definitive paradigm). This means that code blocks are to be defined in procedures (functions) and can be referenced procedure to procedure. Calling one procedure launches the program, in C programming this one procedure is the main() procedure, recognized by name. Any code written outside of a procedure is syntactically incorrect (some exceptions I believe, macros and the like...).
Since correct syntax is the first requirement of program compilation in C (and all other procedural programming languages) the error occurs when attempting to compile and run this code.
I do hope this helps with a greater understanding! Paradigms are fun, they are the rules of using a certain language.
For executing a loop in C, it has to be inside a function. Otherwise compiler will not have any idea when to execute this piece of code. Most of the C compilers will give a compiler error in this case. Only variable initialisations/declarations can appear outside of a function
#include <stdio.h>
int arr[50],i;
/* This piece will not get executed
for(i=0;i<50;i++){
arr[i]=0;
}
*/
int main()
{
printf("Hello World!");
return 0;
}
It has nothing to do with looping in particular. All the statements must be put inside functions, otherwise... tell me, when do you think the code outside a function must be run? Have no idea? And the compiler too
You can initialize an array to 0 by just defining it with the first element initialized to zero.
int arr[50]={0};
What error is thrown when macro and function conflict in C arises?
Is it a macro processor error or does this error occur due to some language violation?
For example, in this code:
#include <stdio.h>
#define MAX(i, j) (i>j)? i : j
int MAX(int i, int j){
return (i>j) ? i : j;
}
int main(){
int max = MAX(5, 7);
printf("%d",max);
return 0;
}
The program throws a compile time error. But I don't understand whether it was some language violation or macro expansion error or something else.
During the preprocessing phase the code gets converted to :
int (int i>int j)? int i : int j{
return (i>j) ? i : j;
}
int main(){
int max = (5>7)? 5 : 7;
printf("%d",max);
return 0;
}
...which, as anyone can tell, is an illegal C code.
(With gcc you could use an -E option to see the preprocessed version of the file.)
Others have pointed out the problem but gave no solutions. The best would be to just use MAX as an inline function. If the macro is in a header, put the inline function definition in the header instead. If you still wish to use a macro (or using an old C compiler which doesn't support inline functions) you can define the function this way:
int (MAX)(int i, int j){
return (i>j) ? i : j;
}
This will prevent the troubling macro expansion and provide MAX as an external function. This will enable you to, for example, assign its address to a variable.
extern int (MAX)(int, int);
...
int (*max_func_ptr)(int, int);
...
max_func_ptr = MAX;
You'll get a compiler error because the macro will be expanded before compilation is attempted.
This is a really nasty problem, and one for which there is not really a solution. For this reason you should avoid defining un-scoped, function-like macros as much as possible, especially in headers that are widely included. Like everything, they have their place, but you need to be careful not to overuse them.
There is no error that occurs specifically to call out that there's a conflict. What happens is that the macro processing occurs first, so in a sense macro definitions respect no name spaces - this is one of the main reasons why macros considered bad form and should be avoided except as a last resort. See this question for an example of a situation where someone's perfectly valid use of the name BitTest for a template was screwed over because someone else decided to create a macro using that name to 'alias' another name: Win32: BitTest, BitTestAndComplement, ... <- How to disable this junk?
So in your example, as other answers have mentioned, once the preprocessing step has occurred, you'll end up with something like the following snippet being passed to the C compiler in place of your function definition:
int (int i>int j)? int i : int j{
return (i>j) ? i : j;
}
This isn't valid C, so you'll get a compiler error that might say (from GCC 3.4.5):
error: syntax error before "int"
or (from MSVC 9):
error C2059: syntax error : 'type'
Which really isn't much help, because when you look at the line the error is refering to in your editor, it'll still look like:
int MAX(int i, int j){
which looks valid.
There are several techniques that are used to help avoid the problem:
use all caps for macro names and only macro names; this is a convention that is largely followed to keep the macro namespace separate from names used for other things
put parens around names that you don't want expanded as macros (this only works for 'function-like' macros). If your example had been written as follows:
int (MAX)(int i, int j){
return (i>j) ? i : j;
}
it would not have resulted in the macro expansion. However, I don't see people doing this very often. One set of utility routines I have uses this technique to protect against macro name collisions, and I often get questions about why all the function names are in parens. Also several editors get confused with function navigation for those files.
avoid using macros; as I mentioned this is one reason that macros are considered bad form. There are other reasons including that they can easily cause the expanded form to produce bad or unexpected expressions if you don't properly use parens around macro parameters or by evaluating a macro parameter that has side effects more than once.
Use inline functions or function templates instead if you can.
As preprocessor macros are only used for processing plain text, these conflicts would always cause a compile time error.
The pre-processing occurs first, so line 4 will become:
int (int i>int j)? int i : int j
which is not valid C.
We are currently developing an application for a msp430 MCU, and are running into some weird problems. We discovered that declaring arrays withing a scope after declaration of "normal" variables, sometimes causes what seems to be undefined behavior. Like this:
foo(int a, int *b);
int main(void)
{
int x = 2;
int arr[5];
foo(x, arr);
return 0;
}
foo is passed a pointer as the second variable, that sometimes does not point to the arr array. We verify this by single stepping through the program, and see that the value of the arr array-as-a-pointer variable in the main scope is not the same as the value of the b pointer variable in the foo scope. And no, this is not really reproduceable, we have just observed this behavior once in a while.
This is observable even before a single line of the foo function is executed, the passed pointer parameter (b) is simply not pointing to the address that arr is.
Changing the example seems to solve the problem, like this:
foo(int a, int *b);
int main(void)
{
int arr[5];
int x = 2;
foo(x, arr);
return 0;
}
Does anybody have any input or hints as to why we experience this behavior? Or similar experiences? The MSP430 programming guide specifies that code should conform to the ANSI C89 spec. and so I was wondering if it says that arrays has to be declared before non-array variables?
Any input on this would be appreciated.
Update
#Adam Shiemke and tomlogic:
I'm wondering what C89 specifies about different ways of initializing values within declarations. Are you allowed to write something like:
int bar(void)
{
int x = 2;
int y;
foo(x);
}
And if so, what about:
int bar(int z)
{
int x = z;
int y;
foo(x);
}
Is that allowed? I assume the following must be illegal C89:
int bar(void)
{
int x = baz();
int y;
foo(x);
}
Thanks in advance.
Update 2
Problem solved. Basically we where disabling interrupts before calling the function (foo) and after declarations of variables. We where able to reproduce the problem in a simple example, and the solution seems to be to add a _NOP() statement after the disable interrupt call.
If anybody is interested I can post the complete example reproducing the problem, and the fix?
Thanks for all the input on this.
That looks like a compiler bug.
If you use your first example (the problematic one) and write your function call as foo(x, &arr[0]);, do you see the same results? What about if you initialize the array like int arr[5] = {0};? Neither of these should change anything, but if they do it would hint at a compiler bug.
In your updated question:
Basically we where disabling interrupts before calling the function (foo) and after declarations of variables. We where able to reproduce the problem in a simple example, and the solution seems to be to add a _NOP() statement after the disable interrupt call.
It sounds as if the interrupt disabling intrinsic/function/macro (or however interrupts are disabled) might be causing an instruction to be 'skipped' or something. I'd investigate whether it is coded/working correctly.
You should be able to determine if it is a compiler bug based on the assembly code that is produced. Is the assembly different when you change the order of the variable declarations? If your debugger allows you, try single stepping through the assembly.
If you do find a compiler bug, also, check your optimization. I have seen bugs like this introduced by the optimizer.
Both examples look to be conforming C89 to me. There should be no observable difference in behaviour assuming that foo isn't accessing beyond the bounds of the array.
For C89, the variables need to be declared in a list at the start of the scope prior to any assignment. C99 allows you to mix assignment an declaration. So:
{
int x;
int arr[5];
x=5;
...
is legal c89 style. I'm surprised your compiler didn't throw some sort of error on that if it doesn't support c99.
Assuming the real code is much more complex, heres some things i would check, keep in mind they are guesses:
Could you be overflowing the stack on occasion? If so could this be some artifact of "stack defense" by the compiler/uC? Does the incorrect value of &foo fall inside a predictable memory range? if so does that range have any significance (inside the stack, etc)?
Does the mcu430 have different ranges for ram and rom addressing? That is, is the address space for ram 16bit while the program address space 24bit? PIC's have such an architecture for example. If so it would be feasible that arr is getting allocated as rom (24bit) and the function expects a pointer to ram (16bit) the code would work when the arr was allocated in the first 16bit's of address space but brick if its above that range.
Maybe you have at some place in your program in illegal memory write which corrupts your stack.
Did you have a look at the disassembly?