This content originally appeared on DEV Community and was authored by Pin Loon Lee
Common function attributes
After my first post, I feel it may be good to continue from low level perspective before going to higher level in term of embedded C/C++ programming for robotics.
There are a lot of common function attributes from documentation of gcc. For this post, I will show examples of usage for only few function attributes which are
__attribute__((warn_unused_result))
__attribute__((deprecated))
__attribute__((__weak__))
Perhaps you have come across with something like below
#ifndef __must_check
#define __must_check __attribute__((warn_unused_result))
#endif
#ifndef __deprecated
#define __deprecated __attribute__((deprecated))
#endif
#ifndef __weak
#define __weak __attribute__((__weak__))
#endif
__attribute__((warn_unused_result))
In some cases, it is very important to force the user to capture the return value of the functions. As shown in below, there is status code that indicates the result of initalization process.
int Init() {
// some status code after certain intiialization process
return status_code;
}
In this case, we would like to avoid calling of function as below
int main(int argc, char **argv) {
Init();
return 0;
}
Thus, we could add the __attribute__((warn_unused_result))
for the function to be like
__attribute__((warn_unused_result))
int Init() {
// some status code after certain intiialization process
return status_code;
}
In this case, if the return value of the function is ignored (calling the function like the example above), user will get a warning as below
warning: ignoring return value of ‘int Init()’, declared with attribute warn_unused_result [-Wunused-result]
__attribute__((deprecated))
Most of the times when we are maintaining a codebase that is used by big group of users, deprecation of code is quite normal but there may be a promised period to maintain the same interface while backward compatibility is also a common requirement. The example below shows how function attributes can help to give a warning to the user when the function called is deprecated.
__attribute__((deprecated)) int Init();
By having the attribute above, user will get a warning as below when calling the function of Init()
.
warning: ‘int Init()’ is deprecated [-Wdeprecated-declarations]
__DEPRECATED_MACRO
As a continuation from marking as deprecation, we could also tag some old macros as deprecated
.
#define __WARN(msg) __WARN_GCC(GCC warning msg)
#define __WARN_GCC(s) _Pragma(#s)
#ifndef __DEPRECATED_MACRO
#define __DEPRECATED_MACRO __WARN("Macro is deprecated")
#endif
If previously we have a macro
#define MAX(a,b) (a > b? a: b)
We can mark it as
#define MAX(a,b) __DEPRECATED_MACRO std::max(a,b)
Calling of the macro would now output
warning: Macro is deprecated
__attribute__((__weak__))
From gcc
documentation,
"The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code, though it can also be used with non-function declarations. Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker."
For example, if we have a
__attribute__((__weak__)) int Init() {
std::cout << "Init is not supported" << std::endl;
return 0;
}
Calling the function would result in output of
Init is not supported
IF there is no other translation unit that provides the definition of the same function.
If there is other file that also provides the definition,
int Init() {
std::cout << "Init done" << std::endl;
return 2;
}
The output of calling Init()
would now be
Init done
The theory is whenever linker found both weak and strong symbol, it would first choose the strong symbol. If there is only weak symbol, it will be chosen. This is valid only for static library (.o .a), it would not work in dynamic (.so) library.
Based on One Definition Rule
,
"objects and non-inline functions cannot have more than one definition in the entire program"
So if you remove the __attribute__((__weak__))
, you will get error that complains about multiple definition.
Here comes the end of the post, hope you enjoy the reading!
This content originally appeared on DEV Community and was authored by Pin Loon Lee
Pin Loon Lee | Sciencx (2022-07-08T12:42:30+00:00) Some common function attributes that I found useful. Retrieved from https://www.scien.cx/2022/07/08/some-common-function-attributes-that-i-found-useful/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.