I found some online resources about this topic but still can not understand how it works.
Lets assume that I have a global variable with following specification
in file: /sys/sys/sysctl.h
#define USER_TZNAME_MAX 20 /*test var*/
and in file /usr/src/sys/kern/kern_mib.c a
SYSCTL_INT(_user, USER_TZNAME_MAX, tzname_max, CTLFLAG_RW, 0, 0, "something");
can anyone show practically how to change the variable value and set another value in a c source file?
Thank you
#define USER_TZNAME_MAX is not defining a global variable, it is a preprocessor macro.
Before the compiler compiles the code the preprocessor is run to expand macros and include/exclude code as defined by definitions.
In an example such as this, the preprocessor will replace all instances of the string "USER_TZNAME_MAX" in the source with the string "20":
// this
int i = USER_TZNAME_MAX;
// will be expanded to this:
int i = 20;
Therefore you can't change this variable at run time because a) it isn't a variable, and b) it's a constant.
If you're talking about changing the value used in your own code you can do this:
#ifdef USER_TZNAME_MAX
#undef USER_TZNAME_MAX
#endif
#define USER_TZNAME_MAX (32)
In programs, you should use sysctl(3) to get or set system information.
Related
I have a macro that should be used both in my source file and header one. However I don't wan't other code linked to the final object to access that macro (more than anything else I don't want the macro to go causing unexpected errors in other files). I thought about using a macro with a long and complicated name that will be unlikely used from other code, however this solution kinda looks ugly to me. Obviously the most simple solution would be to undefine the macro in some way, however if I define the macro in the header and then undefine it – I think – I won't be able to access it anymore from the source file. What should I do?
// hi.h
#define string char *
void greet(string x);
// hi.c
#include "hi.h"
void greet(string x) {
printf("Hi!");
}
Okay, don't kill me, this was just an example, i know #define string char * is horrible.
Last minute thought: Maybe I can underfine the macro at the end of the source file, is this acceptable to do?
I guess you could conditionally "undefine" macro at the end of the header when the a magic macro is not defined. The blessed source file would have to define this macro prior to including a header.
// header.h
...
#ifndef MAGIC_MACRO
#undef string
#endif
// common source
#include "header.h"
// blessed source
#define MAGIC_MACRO
#include "header.h"
This solution will work great as long as no macro defined inside the header uses string macro.
What should I do?
Pick option 1 a macro with a long and complicated name that will be unlikely used from other code as it's the simplest and most obvious. Do not use a complicated name - just use a name so that you and other developers will know it's a private symbol, that's all.
// hi.h
// this macro is private
#define _lib_string char *
Remember about reserved words. Example: https://github.com/GNOME/glib/blob/main/glib/glib-private.h#L32 .
he most simple solution would be to undefine the macro in some way, however if I define the macro in the header and then undefine it – I think – I won't be able to access it anymore from the source file
If you go this way, you'll end up with spaghetti code, where some global state affects what you have. For example:
// hi.h
#define string char *
void greet(string x);
#ifndef FROM_HI_C
#undef string
#endif
// hi.c
#define FROM_HI_C
#include "hi.h"
void greet(string x) {
printf("Hi!");
}
Maybe I can underfine the macro at the end of the source file, is this acceptable to do?
Other files see only the header file - they are unaffected by anything in the source file.
Is there a way to restore macros in C, so that you can define a new macro, under which name probably other macros are already defined, and redefine it with the previous value?
so that when new defined macros are deleted and eventually redefined macros are resetted to its previous state?
Example:
// a macro parameter used in a library
#define size 10
#include <library/use_size.h>
//here the command/pragma to save the definitions
#define size (100 / sizeof(size_t))
// some use of size ...
//here the command/pragma to reset the definitions
#include <library/allocator_with_size.h>
#undef size
// use size as a variable name
size_t size = 0;
//...
size += 123;
Edit: I do not want to use #undef, because it does not restore old macros. Also, if you have many macros, eg for using them in a X-macro-list (in a long repetitive code/declaration of constant arrays and structs), it looks ugly, if there are many #undef directives.
Ok I researched myself and found the pragmas push_macro and pop_macro, supported by clang, gcc and visual c++. I use clang, so it is no problem to use it. The disadvantage: it does not reduce the line-count if you want to restore multiple macros ¹, but it restores the macros and can be encapsulated:
#pragma push_macro("size")
#define size (100 / sizeof(size_t))
#pragma pop_macro("size")
Notes:
¹ I defined multiple macros and tried to restore them with:
#pragma push_macro("size", "key", "name")
// define them all
#pragma pop_macro("size", "key", "name")
But that is not implemented into the compilers yet. So for each macro there must be a seperate line to do this.
I am going through a C code and I found something like this:
#define __UNUSED__
char buf[MAX_BUF_LENGHT];
int errors=0;
What does this mean?
I am not aware that __UNUSED__ is a predefined preprocessor symbol. So it must be a user defined symbol.
I myself have sometimes (test) code or obsolete code in a c-file that I mark-out with #ifdef BLIEP (and BLIEP is normally not defined), but can put it back into compilation by placing a #define BLIEP. Probably the original author of this code did something similar with __UNUSED__.
I need to temporarily overwrite a macro and then restore it. Like:
#define FOO X
#save FOO
#define FOO Y
...
#restore FOO
Is it possible in standard C preprocessor? In GCC?
ADDED. About real world example. I use a global macro for error exception. It acts like assert, but for persistent usage, not only for debug versions; so, for example, I usually call functions (with side-effect) inside the macro. It's defined once, but the definition isn't persistent; therefore I don't know it a-priori. For some piece of code I need its own, modified version of the macro, but I want to save general style of code. It's looks ugly when one part of code uses the one macro, other part uses other macro -- both macros have the same purpose, but slightly different implementation.
So, it's good for me to save original macro temporarily, use different version for a part of code, after that restore original macro.
This is possible with #pragma push_macro and #pragma pop_macro. These are not standard C—they're originally an MSVC extension—but clang supports them, and so does GCC.
Example usage:
int main() {
#define SOME_MACRO 1
printf("SOME_MACRO = %d\n", SOME_MACRO);
#pragma push_macro("SOME_MACRO")
#define SOME_MACRO 2
printf("SOME_MACRO = %d\n", SOME_MACRO);
#pragma pop_macro("SOME_MACRO")
printf("SOME_MACRO = %d\n", SOME_MACRO);
return 0;
}
prints:
SOME_MACRO = 1
SOME_MACRO = 2
SOME_MACRO = 1
You can also #undef a macro inside a push_macro / pop_macro pair, and the pop_macro call will redefine it.
As already said, it is not really possible. Depending on the situation, this might be a workaround:
#include "generalmacrodefs.h" // put them in here or include them indirectly
#undef macro1
#define macro1 "specialized temporary value"
#undef macro1
#include "generalmacrodefs.h" // restores
This requires that generalmacrodefs.h uses a pattern like this at least for the definitions you might temporarily overwrite:
#ifndef macro1
#define macro1 "original value"
#endif
The closest you can come in C is the #undef directive, which simply undefines the macro, allowing it to be replaced:
#define FOO X
...
#undef FOO
#define FOO Y
...
#undef FOO
#define FOO X
The problem is that you cannot know the 'old' value of FOO once you redefine it - so your values must be hard-coded in one place.
You cannot create a macro to save the values for you either, as it isn't possible to have a macro that creates other preprocessor directives in standard C.
So, to start off, here's the code, with actual names switched for generic ones to limit confusion.
/* Get the list of Hotkey commands */
#define A_COMMANDS_MACRO(a, b, c, d) a = b ,
enum {
#include "commandsFile.def"
} ;
#undef A_COMMANDS_MACRO
This is a snippet from some source code I have been looking over and considering forking as a way to familiarize myself with the intricacies of the C programming language. So, to my untrained eye, this appears to do nothing. To my brain, defining something and then immediately undefining it would seem to cancel each other out.
Obviously, I realize that I'm wrong. But why am I wrong?
The "commandsFile.def" file probably uses the "A_COMMANDS_MACRO" macro somewhere internally.
Remember that "#include" essentially pastes the included file into the including one, so the #define is still in effect when "commandsFile.def" is processed.
What you see there is usually called X-MACRO. The technique consists in defining macros via #define, and then including a file that makes use of them with #include.
As a very simple example, you could have a header (say myheader.h) that declared 2 functions in the form of:
int foo(MYTYPE a, MYTYPE_PTR b);
void bar(MYTYPE a, MYTYPE_PTR b);
And then, in your code:
#define MYTYPE int
#define MYTYPE_PTR int*
#include "myheader.h"
#undef MYTYPE
#undef MYTYPE_PTR
The #undefs are sometimes in the included file as well.
For more information, take a look at this Wikipedia link.
The commandsFile.def should contain many lines:
A_COMMANDS_MACRO(A_COMMAND, 10, na, na)
A_COMMANDS_MACRO(OTHER_COMMAND, 23, na, na)
So that the code would create an enum with available commands and their codes.
It could be useful when this .def file is used by a program written in other language, so that instead of implementing text parsing, it uses C preprocessor to do this.