i am currently looking at the HarmonyOS source code, and I can up with a problem. In the image I know that the function doesn't return anything, but what's the LITE_OS_SEC_TEXT part? I havent seen this keyword before, or is it even a keyword like STATIC or typedef. And if so, how do you define a keyword in C?
how do you define a keyword in C?
You don't. It's impossible.
What you can do is to use macros. They are basically just advanced text replacement. The preprocessor is run before the compiler. That is, in principal. On modern compilers they are run at the same time, but the behavior is the same.
If you want to look at the source code after the preprocessor, you can use the -E parameter to the compiler.
Here is an example of how you can make C code more like Pascal. DON'T DO THIS! JUST FOR FUN!
#include <stdio.h>
#define Begin {
#define End ;}
#define Writeln(X) puts(X)
int main(void)
Begin
Writeln("Hello, World!");
Writeln("Hello again")
End
Probably it is a macro. You should look for it's definition in included header files.
You can read about macros here.
Related
Is it mandatory to write #include at the top of the program and outside the main function?
I tried using #define preprocessor inside the main function and it worked fine with only one exception..that being the constant which i defined using the define directive can be used only after the line #define
For instance say printf("%d",PI); #define PI 3.14will give error "Undefined symbol PI". But in the following code i did not encounter any error
#define PI 3.14
printf("%d",PI);
Is this because C is a procedural language and procedural languages implements top down approach?
Also i would like to know that can we use only #define inside the main function or other preprocessor directives too? If we can use then which ones?
Or is it the other way around, instead of #include we can use all the preprocessor directives in the main function?
The only place you can't put a preprocessor directive is in a macro expansion. The sole exception is #pragma, which can also be written _Pragma().
This has nothing to do with "procedural", but due to the fact that C is defined in terms of 8 translation phases, each of which is "as-if" fully-completed before the next phase. For more details, see the C11 standard, section 5.1.1.2.
One example of when it is useful to use preprocessor directives after the start of a file is for the "X Macro" technique (which many people only know as "those .def files").
Preprocessor directives work pretty much anywhere. Of course, you can make your code confusing pretty easily if you abuse this.
The pre-processor does its work before the compiler performs the source code translation into object code. Pre-processing is mostly a string replacement task, so it can be placed just about anywhere in your code. Of course, if the resulting expansion is syntactically incorrect, the expanded source code will fail to compile.
A commonly tolerated practice is to embed conditional compilation directives inside a function to allow the function to use platform specific APIs.
void some_wrapper_function () {
#if defined(UNIX)
some_unix_specific_function();
#elif defined(WIN32)
some_win32_specific_function();
#else
#error "Compiled on an unsupported platform"
#endif
}
By their nature, the directives themselves normally have to be defined at the beginning of the line, and not somewhere in the middle of source line. But, defined macros can of course appear anywhere in the source, and will be replaced according to the substitution rules defined by your directives.
The trick here is to realize that # directives have traditionally been interpreted by a pre-processor, that runs before any compilation. The pre-processor would produce a new source file, which was then compiled. I don't think any modern compiler works that way by default, but the same principles apply.
So when you say
#include "foo.h"
you're saying "insert the entire contents of foo.h into my source code starting at this line."
You can use this directive pretty much anywhere in a source file, but it's rarely useful (and not often readable) to use it anywhere other than at the start of the source.
I am testing two versions of the same code (with GCC version 4.9.2 on Linux, no parameters).
Both have a #define directive, followed by an #ifdef/#endif pair further down.
Now, it turns out that the combination works properly only if the label after the initial #define starts with an underscore. Without the underscore, it works.... in a very weird way, only every third time.
In other words, this works
#define _whatever
while this doesn't:
#define whatever
Even though I know how to make the directive work, just curious - does that behavior follow any standard?
Edit:
Following requests below, here's two absolutely real examples.
This one prints the line "Preprocessor works":
#define _whatever
#include <stdio.h>
void main()
{
#ifdef _whatever
printf("Preprocessor works \n");
#endif
}
... and this one doesn't output anything:
#define whatever
#include <stdio.h>
void main()
{
#ifdef whatever
printf("Preprocessor works \n");
#endif
}
Yes, I am even using the word "whatever" literally - I don't think, it is defined anywhere else. But again, it's the underscore that makes the label work.
There is absolutely no requirement, in any known version of gcc, that preprocessor macros begin with an underscore.
As a general rule, preprocessor macros that begin with various combinations of underscores are reserved to the implementation, and users are advised to ignore them. So #define whatever and #ifdef whatever absolutely must work.
I agree that this is a baffling and frustrating problem. There's something strange going on, but whatever the explanation is, it's not that gcc is requiring leading underscores.
Ok, so the answer is - my sloppy command of the tools.
Specifically:
(1) I was using a header file to add/remove the #define directive
(2) I have (mindlessly) compiled the header by using "gcc *" in place of "gcc *.c"
(3) The occasional presence of the compiled *.h.gch file explains the results.
So, what seemed like erratic behavior was actually me (mindlessly) removing the *.h.gch from time to time.
Thanks everyone - I have learned a lot from all the replies.
How do I interpret this C code:
typedef enum {
#include <test.h>
enum1,
enum2,
…
} test_enum;
test.h includes many macros. How to understand this?
Does means that the definitions of the enum needs the macros defined inside the header file?
Can #include appear anywhere?
An #include statement may appear on any line. It is most often used to include entire declarations. However, it can be used to insert any text.
It may be that test.h contains a list of names to be declared inside the enum. It may also contain preprocessor statements, such as macro definitions or #if … #endif statements.
You would have to show the contents of test.h for further help understanding it.
#include and #define are pre processor directives not actual code.
You can put them anywhere (except as part of a literal string) - some compilers are more fussy than others (i.e. the # has to be in column 0).
The Preprocessor expands these out as required, and that is what the compiler sees. As to what it means in your case, depends on the content of test.h
There is normally a compiler option to see your code with all the preprocessor stuff expanded (used to be -e or -E on gcc I think)
The #include directive causes the contents of the included file to be placed exactly at the point of the #include directive. The resulting code is what it is once that expansion has taken place, and can be any valid language construct.
If the included file contains:
enum_a,
enum_b,
enum_c,
Then after inclusion, your code would look like:
typedef enum {
enum_a,
enum_b,
enum_c,
enum1,
enum2,
…
} test_enum;
Which is a valid construct.
A #include directive can appear anywhere. See this.
Pre-processor statements can occur anywhere and are simple textual substitutions. Whether or not the processed code is valid C code is checked by the compiler, not the pre-processor.
Depending on your compiler you can review the changes done by the pre-processor.
For gcc, this would be the -E flag, so by compiling your source code with
gcc -E in.c
you can see which changes code is contained in the enum declaration after inserting test.h and
processing it.
I am trying to understand the idea of function like Macros however there are a few points that befuddle me. For example say we have:
#define Max(a,b) ((a)>(b)) ? (a):(b))
and I call it like such
int i = Max(4,5);
This will evaluate a conditional expression equivalent to a>b? If yes then a, else b. But I'm confused as to how the Max function knows what to do with the arguments. Unlike an actual function, the implementation isn't written in code in the calling program. is the statement to the right of the define statement doing this for me? Its just a new thing for me and I want to make sure I understand what is happening here.
This particular part of function like macros confuses me. I know that these types of macros are useful for reducing overhead costs since they exclude the JSR RTS processor instructions which saves memory on the stack.
#define Max(a,b) ((a)>(b)) ? (a):(b))
is a macro, that causes nothing else but a simple textual replacement within your code, which means that during the preprocessing this line:
int i = Max(4,5);
is changed into:
int i = ((4)>(5)) ? (4):(5));
Note that there is no type safety while working with macros like this one and you will have really hard time while debugging your code as well. Good rule of thumb is: Don't use macro when you can achieve the same with function:
int max(int a, int b) {
return (a > b) ? a : b;
}
What the compiler actually sees, after preprocessing, is:
int i = ((4)>(5)) ? (4):(5));
The parameters passed to the macro are substituted into the body of the macro.
Just stop thinking about macro like compilable code. Macros are "resolved" by pre-processor, not actually during compilation stage. So by macro definitions you just define how to process certain string in text file. Only output of pre-processor is passed to compiler. You can use gcc -E to see your source after pre-processor. It is still C code on this stage but without any preprocessor directive.
Hope this will help you.
try to build your code with the gcc -E and see how your code look before compiling it
In fact in the build process the compilator transform your actual code to a preprocessor code.
In the preprocessor phase the compilator replace all macro in your c code with its content and generate another code called preprocessor code and then the compilateor generate the object code from the preprocessor code
The gcc -E allow you to see your preprocessor code
first of all, I'm using MS's Visual Studio and using C language.
Recently I need to declare variables with just one same statement which likes a macro.
However as you know, I can declare just one variable which have same name.
for example, this is not possible.
int iVar1;
int iVar1; // this is not possible.
so I thought about macros include __LINE__ , if I can use this predefined macro, I can declare lots of variables via just one macro statement.
But it was difficult to make.
I made macro like this.
#define MY_LINE_VARIABLE int g_iLine##__LINE__##Var = 0;
but after compile, i could get this variable named 'g_iLine_LINE_Var' instead of 'g_iLine123Var'
I want to know that is this possile, and how can i make it.
Furthermore, I need to use __FILE__ macro if possible. but this macro might be changed with string data. so I can not be sure.
Any advice will be helpful.
Thank you for your help in advance.
As #Chris Lutz has rightly said that, there might be a better way to accomplish what you want. Consider asking what you want to achieve.
But if you are just curious, this is the way to do:
#define var(z) int g_iLine##z##var = 0
#define decl(x) var(x)
#define MY_LINE_VARIABLE decl(__LINE__)
MY_LINE_VARIABLE;
MY_LINE_VARIABLE;
From this link :
After the preprocessor expands a macro name, the macro's definition
body is appended to the front of the remaining input, and the check
for macro calls continues. Therefore, the macro body can contain calls
to other macros.
So in your case :
MY_VARIABLE_LINE is converted to int g_iLine__LINE__Var;. But now __LINE__ is not a valid token anymore and is not treated as a predefined macro.
Aditya's code works like this:
MY_VARIABLE_LINE is converted to decl(__LINE__) which is converted to var(123) which is converted to int giLine123var = 0.
Edit: This is for GNU C