(C) Function which impersonates a block of code in main - c

I'm trying to explain this satisfactorily, but when I call a function I want it to virtually insert itself into the main function's code in the place where I call it, so I can save typing it out multiple times, however it directly affects variables defined in the scope of the main function. What's the best way to achieve this?
EDIT: I should probably make it clear I also want it to take a single argument.

Sounds like you need a preprocessor macro. These aren't real functions, but blocks of code the the preprocessor replaces before compiling the code. E.g., consider a simple macro to increment a number:
#include <stdio.h>
#define INC(x) (x)++
int main() {
int a = 1;
INC(a);
INC(a);
printf("%d\n", a);
return 0;
}
The text INC(a) will be replaced with a++, so running this program will print out 3 (1 after two increments).

Related

C program using user defined

void fun()
{
// Essentially this is a function with an empty body
// And I don't care about () in a macro
// Because this is evil, regardless
#define printf(a, b) (printf)(a, b*2)
}
void main() // I know this is not a valid main() signature
{
int x = 20;
fun();
x = 10;
printf("%d", x);
}
I am having doubt with #define line ! Can you please give me some links documentation for understanding this line of code.Answer is 20.
The #define defines a preprocessor macro is processed by the preprocessor before the compiler does anything.
The preprocessor doesn't even know if the line of code is inside or outside a function.
Generally macros are defined after inclusion of header files.
i.e. after #include statements.
Preprocessor macros are not part of the actual C language, handling of macros and other preprocessor directives is a separate step done before the compiler1. This means that macros do not follow the rules of C, especially in regards to scoping, macros are always "global".
That means the printf function you think you call in the main function is not actually the printf function, it's the printf macro.
The code you show will look like this after preprocessing (and removal of comments):
void fun()
{
}
void main()
{
int x = 20;
fun();
x = 10;
(printf)("%d", x*2);
}
What happens is that the invocation of the printf macro is replaced with a call to the printf function. And since the second argument of the macro is multiplied by two, the output will be 10 * 2 which is 20.
This program illustrates a major problem with macros: It's to easy to a program look like a normal program, but it does something unexpected. It's simple to define a macro true that actually evaluates to false, and the opposite, changing the meaning of comparisons against true or false completely. The only thing you should learn from an example like this is how bad macros are, and that you should never try to use macros to "redefine" the language or standard functions. When used sparingly and well macros are good and will make programming in C easier. Used wrongly, like in this example, and they will make the code unreadable and unmaintainable.
1 The preprocessor used to be a separate program that ran before the compiler program. Modern compilers have the preprocessor step built-in, but it's still a separate step before the actual C-code is parsed.
Let me put this in another way.
printf() is an inbuilt standard library function that sends formatted output to stdout (Your console screen). The printf() function call is executed during the runtime of the program. The syntax looks likes this.
int printf(const char *format, ...)
But this program of yours replaces the printf() function with your macro before the compilation.
void fun(){
#define printf(a, b) printf(a, b*2)
}
void main() {
int x = 20;
fun();
x = 10;
printf("%d", x);
}
So what happens is, before compilation the compiler replaces the inbuilt function call with your own user defined macro function with two arguments:
a="%d" the format specifier and
b=the value of x =10.
So the value of x*2 =20

C macro, something weird

Trying to figure out something simple in a C macro,
like this code for example:
#include <stdio.h>
#define MACRO(b) printf("%d\n", b*b)
int main()
{
MACRO(4+1);
}
The output for this code is 9, I think that it should be 25.
I don't have any idea why and how the result for this is 9 and not 25.
When you use the macro, the preprocessor replaces it and its arguments quite verbatim, so the macro expansion in your code will look like
printf("%d\n", 4+1*4.1);
That will not provide you with the result you want, and it is one of the reasons that function-like macros are looked down upon.
You need to use parentheses to make sure this problem doesn't occur:
#define MACRO(b) printf("%d\n", (b)*(b))
while will then result in the following expansion:
printf("%d\n", (4+1)*(4.1));
Whenever you have problems with something preprocessor related, there are options for just about all compilers to stop after the preprocessing stage, which allows you to look at the preprocessed source and which will help you with problems like this.
Also note that another possible problem here is if the expression you pass as argument to the macro is e.g. a function call with some side-effect that function will be called twice and the side-effect will be happen twice, even when using parentheses.
A simple example, using your macro:
int my_function(void)
{
printf("Foo\n");
return 1;
}
int main(void)
{
MACRO(my_function());
}
The above program will print "Foo\n" twice. If MACRO was a proper function the call to my_function would only happen once and the printout from the function would only happen once.
Put parentheses around your macro to evaluate arguments in the correct order:
#include <stdio.h>
#define MACRO(b) printf("%d\n", (b)*(b))
int main()
{
MACRO(4+1);
}

Issue with for loop in C

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};

Multiple definition of main()

Hi guys trying to use two main() and getting this error multiple definition of main(). I renamed my main functions then why is this error and also first defined here for my print().
header file:
#ifndef TOP_H_
#define TOP_H_
#include <stdio.h>
#include <string.h>
#define onemain main
#define twomain main
inline void print();
#endif /* TOP_H_ */
c file one:
#include "top.h"
void print();
int onemain()
{
print();
return 0;
}
void print()
{
printf("hello one");
}
c file two:
#include "top.h"
void print();
int twomain()
{
print();
return 0;
}
void print()
{
printf("hello two");
}
Basically any C (or even C++) program is a bunch of functions calling each other.
To begin a program execution, you have to pick one of these functions and call it first.
By convention, this initial function is called main.
When you include several source files in a project, the IDE compiles them all, then calls the linker which looks for one single function called main and generates an executable file that will call it.
If, for any reason, you defined two "main" functions inside all these files, the linker will warn you that it cannot choose on its own which one you intended to be the starting point of your program.
The macro substitution of onemain and twomain occurs before the compiler proper sees the program, so that doesn't make a difference. The functions are both named main.
C++ allows different functions with the same name, but does not allow two definitions of the exact same function signature. There would be no way to form a function call expression that would reach either overload. Additionally, the functions are the same entity, and one thing cannot have two definitions.
In addition, in C++ main cannot be overloaded, because the program is supposed to start when the unique main function is called, and any given system detects what format of main the particular program uses, out of a variety of allowed formats. (This auto-detection feature also applies to C.)
But you are not asking about C++; in C, without function overloading, there are no redefinitions of the same name, even for different signatures. Each name of extern linkage in C uniquely identifies an entity, so you cannot have two.
It's unclear what you want the resulting program to do. Most likely you need to build two separate programs.
I don't get what you ask - your error messages are quite clear:
You have 2 definitions of print(), which will collide. Remove one.
You as well have 2 definitions of main() - your #defines will replace your onemain and twomain functions, naming them effectively as main.
You overrode the built in print, about main, try imagining a car with two steering wheels ... it wont work ...
Your C program has two have a least one main, so the computer knows where the program starts.
If you have 2 files with two main function, then you have two different programs.
It's not possible for a C program to have more than one main() in it. Also, main() should be declared as an int and return an integer value (usually 0).

Putting variable declarations in a separate function in C

Is it possible to put the variable declarations in an external function? After reading from Wikipedia that:
an inline function is a function upon which the compiler has been requested to perform inline expansion. In other words, the programmer has requested that the compiler insert the complete body of the function in every place that the function is called, rather than generating code to call the function in the one place it is defined.
I hypothesized that the following might work. It did not take long for the compiler to slap my fingers :(
inline void declaration(){
int a;
}
int main(){
declaration();
a=2;
return 0;
}
This may not be how it is done but if you want a basic idea of how you can think about what happens when you inline a function.
Imagine the compiler turning your code into something like this, then you see why it will not work.
int main(){
{
int a;
}
a=2;
return 0;
}
The call to declaration() is replaced by the contents of the function including brackets, thus int a; is declared in an inner scope and is not visible in the main function.
No, this is not possible.
What is possible, is to use a preprocessor directive #define:
#define VARBLOCK int a, b, c; char ca, cb, cc;
int main()
{
VARBLOCK;
a = 2;
}
This would be a bad practice. Also these would still be variables only available in the scope of function where it were placed, without values being shared.
No - as far as I'm aware an inline function must behave semantically equivalent to a non-inline function; it doesn't affect what counts as legal code. It's just an optimization.
In particular, you could have a variable called a in both functions, but they'd be separate variables on the stack.
(Even if you could do this, I'd suggest it would be a very bad idea in terms of readability.)
inline functions are usually just a function containing no more than about 4 lines and you would want the compiler to do the optimization you where talking about since it would be faster to do what the function does, rather than adding extra code.
Inline expansion is used to eliminate the time overhead when a function is called. It is typically used for functions that execute frequently.
So there's nothing special with the inline function, rather than it might be handled differently by the compiler. They don't share their stack with any other function, which would be the only way for main to use a variable that is created in a different scope.
So my tip is; write your functions, and treat them as you usally should. Then when you are done, inline the short ones that you use a lot.
And if you really wanna create a variable in another function, allocate it on the heap in the function and return a pointer that you save and then set to 2 (your case). :) Just remember to free the memory!
You can do this, though:
#include <stdio.h>
int* GetMyIntAddress(void)
{
static int blah = 0;
return &blah;
}
int main(void)
{
printf("%d\n", *GetMyIntAddress());
*GetMyIntAddress() = 123;
printf("%d\n", *GetMyIntAddress());
return 0;
}
blah will be a global variable defined in the scope of the GetMyIntAddress() function.
If you add inline to the definition of GetMyIntAddress(), you are risking to get multiple independent instances of blah if the inline function is used in different modules (e.g. included from a shared header file).

Resources