importance of using macro STATIC - c

I have some legacy code, which uses the macro definition as
#ifdef def_STATIC
#define STATIC static
#else
#define STATIC
#else
#endif
I understand using STATIC will help limiting the scope of variables depending on def_STATIC
but in what cases is this practice used ?
How is it helpful ?

I have never faced such macro myself, but according to this: "XFS removal of #define STATIC static" source it was used to disable static functions because GDB couldn't properly debug static inline functions. That's why this macro was used to temporarily make them non-static.
Correct me if I'm wrong, I've just googled it :)
An interesting question really)

Related

Why to replace static function as object-like macro, #define STATIC static?

I just spotted this in the legacy code. I know that using the macro, whenever the name is used, it is replaced by the contents of the macro. They are most commonly used to give symbolic names to numeric constants.What I know is preprocess has no notion of type safety, scope.
What is the real benefit of doing like this?
#define STATIC static
STATIC function1() { /*Do something*/ }
I knew that static functions are visible only in that module or translation unit. Not visible outside of the C file they are defined.
Why not just declare like this, instead of macro replacement?
static function1() { /*Do something*/ }
I thought I will find an answer in SO but I didn't find any proper answer.
There is no rational reason why you would do this. Generally it is bad practice to hide keywords behind #define in this manner, because the code turns cryptic and harder to read.
I would suspect it has to do with coding style, it is common to write various function specifiers in upper case, particularly in Windows programming. Often it is done to specify a certain calling convention. For example CALLBACK in Windows, or this example from the old "Windows bible" (Petzold):
#define EXPORT __declspec (dllexport)
(Which could be modified to also contain extern "C" in case of C++.) You'd then have a function such as EXPORT void CALLBACK func (void). Similarly there's also WINAPI in Windows.
Sometimes we also see things like
#define PRIVATE static
which is kind of horrible, because static doesn't really have the same meaning as private in C++.

Looking for preprocessor command to remove command in code

I am working on a C library which sometimes uses
static inline void myfunc(...)
when defining a function.
Now I try to port this to an old C compiler that does not support "static inline". This is bcc - Bruce's C compiler.
Can I use a command in a header file that replaces
static inline void
with
void
in all programs that include this header file?
When you must target a compiler that does not support certain features, it is common to use macros in your code, rather than trying to modify your code with macros.
In this situation you can define STATIC_INLINE macro in a compiler-dependent way, and use it like this:
#ifdef BCC_COMPILER
#define STATIC_INLINE
#else
#define STATIC_INLINE static inline
#endif
...
STATIC_INLINE void myfunc(...)
Thank you very much to all for the help. I have to report that BLUEPIXY gave the answer that worked for me in his comment:
#define inline
Apparently bcc does accept static void but not static inline void.

nesting preprocessor directives or other trickery to conditionally redefine the static keyword

I am using unity for unit testing.
I have a header throughout my project that I include with some helper macros, like an assert wrapper that I can use to track which assert fired.
In that header I also have the following definition:
#define static //nothing
I learned that little trick from this article:
http://www.embedded.com/design/programming-languages-and-tools/4007177/2/Doing-C-code-unit-testing-on-a-shoestring-Part-1-The-basics-and-the-tools
This allows me to write unit tests for static functions and it allows me to access any relevant file scope data from my test harness.
The trouble is this totally breaks static at the function scope. The article goes on to say if I do this:
#define static extern
Then any variable that is static at the function scope can then be defined within the test harness. We're off to the races, right? Not exactly.
Because the following occurs
void foo()
{
extern bool my_flag = false;
}
Now we are supplying an initializer to declaration, which is invalid. So that means any static variable I handled this way would inherently need to be initialized after startup.
Because static variables within functions are relatively uncommon, I thought I might circumvent this by defining a new symbol, LOCAL_STATIC. So now in my header I have the following
#define static extern
#define LOCAL_STATIC static
But that does not work because those directives are evaluated strictly in order - #define LOCAL_STATIC static becomes #define LOCAL_STATIC extern, or at least that is what seems to be happening. Because LOCAL_STATIC produces the same error and indeed ends up getting changed to extern by the preprocessor.
So is there any way around this?
AFAIK anything like this is impossible:
#define LOCAL_STATIC \
#undef static \
static \
#define static extern
The only thing I can think of is to leave static alone and define a new symbol, something like HARNESS_ACCESSIBLE.
#ifdef UNIT_TEST
#define HARNESS_ACCESSIBLE extern
#else
#define HARNESS_ACCESSIBLE static
#endif
But that is going to clutter up the production code with this new weird thing "HARNESS_ACCESSIBLE". Static variables within functions are generally rare, but almost all static functions (except trivial helper functions) will need to be externally accessible by my test runner.
I've been trying to avoid writing a separate script that has to run before builds, but I am getting to that point now.
I think your idea of creating a HARNESS_ACCESSIBLE macro is the cleanest way of going about this. You definitely don't want to be #define-ing away static for just the reasons you described.
I don't think using this macro will be cluttering up your code. You'll just be putting this in place of static, and it gives you the option of specifying exactly which functions you want to be able to unit test and keeping those minor utility functions explicitly static.

Why define a macro insted of using directly?(Please see description for what exactly i want)

I am traversing through linux kernel code. I found a macro defined as #define __async_inline __always_inline. I searched for __always_inline,I found the following statement #define __always_inline inline. My question is why they need to do like this? They can directly use inline instead of this macro's?
The code says this:
#ifdef CONFIG_HAS_DMA
#define __async_inline
#else
#define __async_inline __always_inline
#endif
It is self-explained. __async_inline will be replaced by inline if CONFIG_HAS_DMA is not defined.
This is a common way to parameterize code, to move a decision of some sort (in this case, the use of inline) to a single place, so that should that decision change (for whatever reason: different compilers, different configuration options, different architectures), there is only one single place to change.

How to avoid that C-header overwrites native C++ type

First I have to explain my ...
Situation
I have this microcontroller code (plain old C) which includes bool.h with the following content since stdbool.h is apparently not available, especially not with Visual Studio 2008, which is my current IDE for VC++ and C# (see below):
#ifndef CUSTOM_BOOL
#define CUSTOM_BOOL
#ifdef __cplusplus
extern "C" {
#endif // #ifdef __cplusplus
#ifndef bool
#define bool unsigned char
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#ifdef __cplusplus
}
#endif // #ifdef __cplusplus
#endif // #ifndef CUSTOM_BOOL
Now I need the functionality of that microcontroller code in a C# Project. That's why I created an intermediate Visual C++ Project containing managed classes that wrap the given microcontroller code.
Since this wrapper project (VC++) fiddles about the C code, it also has to #include "bool.h" (in an indirect way however, which means that another header is included, which itself includes bool.h - but I think that's an unimportant detail). Now here's my ...
Problem
Due to the fact that bool.h is included in the VC++ project and this project shall provide functions that return a "real" bool ("real" here means a type that is recognized as a bool by C# when using the VC++ project), unfortunately the bool in the VC++ code is also caught by the preprocessor and thus replaced by unsigned char. What happens now is, that C# complains in the end that a conversion from unsigned char to bool is not allowed. This is all okay and I understand why this happens. So here's my ...
Question
How can I solve this issue in a "clean" way. My current solution is, after including bool.h and right before the VC++ code starts, I undefine bool and friends again like this:
#ifdef bool
#undef bool
#endif
#ifdef true
#undef true
#endif
#ifdef false
#undef false
#endif
It works, but it breaks my proper-way-of-programming-heart. Is there a proper way to fix this? Or is the problem maybe happening before? Should I instead define something like BOOL instead of bool? According to my search on the interwebz, there is no general "standard" way to define bool (or BOOL?) in a C project (C99 is not supported) that everybody would agree upon.
So it sounds like the microcontroller project just made up a new data type and called it bool, which happens to conflict now that bool is a keyword (along with true and false)? My suggestions (in order of preference) would be:
Solution 1: Fix the microcontroller project.
Do a global search and replace on bool and replace it with something less contentious. Maybe C_Boolean, C_True, and C_False. Unlikely to cause any future conflicts and fairly simple to do using regular expressions.
Solution 2: Convert microcontroller project to C++.
This allows direct use of bool, true, and false (as keywords) and you can just eliminate the macros. This may prove difficult if the microcontroller code uses syntax that isn't c++ compatible.
Solution 3: Do what you've already done.
Create a wrapper include which cleans up after including your microcontroller code. I've got code that relies on redefining the extern keyword and this ends up being the only safe way for me. It's fragile though...you'll likely have to fix it in the future when something unrelated breaks the include structure.
Also, I'm not sure what the original author believes the extern "C" wrappers are doing but they have no effect on the macros being defined. Maybe you cut out some stuff that it would have an effect on, but the macros are unaffected by the linker name conventions.
You could convert the return value (the char) to a boolean value by using an operator. In this case, for instance, you could simply compare the return value this way:
bool b = 0 != functionthatreturnsaboolean();
Note that I'm not using 1 since the usualt definition of a boolean is 0 for false, anything else otherwise.
The other solution would be to simply use another type of return value. An integer should work well.
Edit: In light of the comment - you could also simply create an interface that calls those functions and returns a C# boolean value.
bool interfacefunction()
{
return function() != 0;
}
Thanks to Keith Thompson (comment under the question) and Speed8ump's answer, I got another idea:
bool.h:
#ifndef CUSTOM_BOOL
#define CUSTOM_BOOL
#ifndef __cplusplus
#ifndef bool
#define bool unsigned char
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#endif // #ifndef __cplusplus
#endif // #ifndef CUSTOM_BOOL
Works like a charm and I think it's a cleaner solution than the undefining stuff before. But still, feel free to comment or to provide more / better answers.

Resources