gcc has __attribute__((weak)) which allows to create a weak symbol such as a function. This allows the user to redefine a function. I would like to have the same behavior in XC8.
More info:
I am writing a driver for XC8 and I would like to delegate low level initialization to a user defined function.
I know it is possible to redefine a function: there is the putch function that is implemented in XC8's source file and which is called by the printf function. The user is allowed to reimplement putch inside his application. There are two functions with the same name, but no error is raised.
putch's implementation in XC8's source files has a comment saying "Weak implementation. User implementation may be required", so it must be possible.
I looked at pragmas in XC8's user guide, but there is no directive related to this question.
A linker will only search static libraries to resolve a symbol that is not already resolved by input object files, so replacing static library functions can be done without weak linkage. Weak linkage is useful for code provided as source or object code rather then as a static library.
So if no weak linkage directive is supported, you could create a static library for the "weak" symbols and link that.
The XC8 manual documents behaviour for both the IAR compatibility directive __weak and a weak pragma, and in both cases the directives are ignored (supported only in XC16 and XC32), so you will have to use the above suggested method, which is in any case far more portable - if somewhat inconvenient.
In the case of putch() I suspect that this is not working as you believe. I would imagine that this is not a matter of weak linkage at all; in the static library containing printf() an unresolved link to putch() exists, and the linker resolves it with whatever you provide; if you were to compile and link both the Microchip implementation and yours from source code you would get a linker error; equally if you were to provide no implementation whatsoever you would get a linker error.
XC8 compiler does support the "weak" attribute.
The weak attribute causes the declaration to be emitted as a weak symbol. A weak symbol indicates that if a global version of the same symbol is available, that version should be used instead. When the weak attribute is applied to a reference to an external symbol, the symbol is not required for linking.
For example:
extern int __attribute__((weak)) s;
int foo(void)
{
if (&s)
return s;
return 0; /* possibly some other value */
}
In the above program, if s is not defined by some other module, the program will still link but s will not be given an address.
The conditional verifies that s has been defined (and returns its value if it has). Otherwise '0' is returned.
There are many uses for this feature, mostly to provide generic code that can link with an optional library.
A variable can also be qualified with the "weak" attribute.
For example:
char __attribute__((weak)) input;
char input __attribute__((weak));
Related
I am trying to implement a global singleton variable in the header-only library in C (not C++). So after searching on this forum and elsewhere, I came across a variation of Meyer's singleton that I am adapting to C here:
/* File: sing.h */
#ifndef SING_H
#define SING_H
inline int * singleton()
{
static int foo = 0;
return &foo;
}
#endif
Notice that I am returning a pointer because C lacks & referencing available in C++, so I must work around it.
OK, now I want to test it, so here is a simple test code:
/* File: side.h */
#ifndef SIDE_H
#define SIDE_H
void side();
#endif
/*File: side.c*/
#include "sing.h"
#include <stdio.h>
void side()
{
printf("%d\n",*(singleton()));
}
/*File: main.c*/
#include "sing.h"
#include "side.h"
#include <stdio.h>
int main(int argc, char * argv[])
{
/* Output default value - expected output: 0 */
printf("%d\n",*(singleton()));
*(singleton()) = 5;
/* Output modified value - expected output: 5 */
printf("%d\n",*(singleton()));
/* Output the same value from another module - expected output: 5*/
side();
return 0;
}
Compiles and runs fine in MSVC in C mode (also in C++ mode too, but that's not the topic). However, in gcc it outputs two warnings (warning: ‘foo’ is static but declared in inline function ‘singleton’ which is not static), and produces an executable which then segfaults when I attempt to run it. The warning itself kind of makes sense to me (in fact, I am surprised I don't get it in MSVC), but segfault kind of hints at the possibility that gcc never compiles foo as a static variable, making it a local variable in stack and then returns expired stack address of that variable.
I tried declaring the singleton as extern inline, it compiles and runs fine in MSVC, results in linker error in gcc (again, I don't complain about linker error, it is logical).
I also tried static inline (compiles fine in both MSVC and gcc, but predictably runs with wrong output in the third line because the side.c translation unit now has its own copy of singleton.
So, what am I doing wrong in gcc? I have neither of these problems in C++, but I can't use C++ in this case, it must be straight C solution.
I could also accept any other form of singleton implementation that works from header-only library in straight C in both gcc and MSVC.
I am trying to implement a global singleton variable in the header-only library in C (not C++).
By "global", I take you to mean "having static storage duration and external linkage". At least, that's as close as C can come. That is also as close as C can come to a "singleton" of a built-in type, so in that sense, the term "global singleton" is redundant.
Notice that I am returning a pointer because C lacks & referencing available in C++, so I must work around it.
It is correct that C does not have references, but you would not need either pointer or reference if you were not using a function to wrap access to the object. I'm not really seeing what you are trying to gain by that. You would likely find it easier to get what you are looking for without. For example, when faced with duplicate external defintions of the same variable identifier, the default behavior of all but the most recent versions of GCC was to merge them into a single variable. Although current GCC reports this situation as an error, the old behavior is still available by turning on a command-line switch.
On the other hand, your inline function approach is unlikely to work in many C implementations. Note especially that inline semantics are rather different in C than in C++, and external inline functions in particular are rarely useful in C. Consider these provisions of the C standard:
paragraph 6.7.4/3 (a language constraint):
An inline definition of a function with external linkage shall not contain a definition of a modifiable object with static or thread storage duration, and shall not contain a reference to an identifier with internal linkage.
Your example code is therefore non-conforming, and conforming compilers are required to diagnose it. They may accept your code nonetheless, but they may do anything they choose with it. It seems unreasonably hopeful to expect that you could rely on a random conforming C implementation to both accept your code for the function and compile it such that callers in different translation units could obtain pointers to the same object by calling that function.
paragraph 6.9/5:
An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression [...], somewhere in the entire program there shall be exactly one external definition for the identifier [...].
Note here that although an inline definition of a function identifier with external linkage -- such as yours -- provides an external declaration of that identifier, it does not provide an external definition of it. This means that a separate external definition is required somewhere in the program (unless the function goes altogether unused). Moreover, that external definition cannot be in a translation unit that includes the inline definition. This is large among the reasons that extern inline functions are rarely useful in C.
paragraph 6.7.4/7:
For a function with external linkage, the following restrictions apply: [...] If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.
In addition to echoing part of 6.9/5, that also warns you that if you do provide an external definition of your function to go with the inline definitions, you cannot be sure which will be used to serve any particular call.
Furthermore, you cannot work around those issues by declaring the function with internal linkage, for although that would allow you to declare a static variable within, each definition of the function would be a different function. Lest there be any doubt, Footnote 140 clarifies that in that case,
Since an inline definition is distinct from the corresponding external definition and from any other corresponding inline definitions in other translation units, all corresponding objects with static storage duration are also distinct in each of the definitions.
(Emphasis added.)
So again, the approach presented in your example cannot be relied upon to work in C, though you might find that in practice, it does work with certain compilers.
If you need this to be a header-only library, then you can achieve it in a portable manner by placing an extra requirement on your users: exactly one translation unit in any program using your header library must define a special macro before including the header. For example:
/* File: sing.h */
#ifndef SING_H
#define SING_H
#ifdef SING_MASTER
int singleton = 0;
#else
extern int singleton;
#endif
#endif
With that, the one translation unit that defines SING_MASTER before including sing.h (for the first time) will provide the needed definition of singleton, whereas all other translation units will have only a declaration. Moreover, the variable will be accessible directly, without either calling a function or dereferencing a pointer.
I'm writing a library and have some __weak functions which need to be overwritten by the programmers. I want to make sure they do so, so I did this:
__weak void checkButtons(){
#warning "Implement this"
}
And put the prototype in the header:
__weak void checkButtons();
And implement it in another file:
void checkButtons(){
//Some codes here
}
By the way, the problem is that in compile time, the compiler shows the #warning message.
compiling library.c...
library.c(8): warning: #1215-D: #warning directive: message "Implement this"
#warning message "Implement this"
library.c: 1 warning, 0 errors
I think if a __weak function is overridden, the main function should not be compiled, should be?
I don't know why this happens. Any other idea to force the user?
the main function should not be compiled, should be?
Everything is compiled. Weak functions are compiled, normal functions are compiled. The linker when linking the program chooses (the compiled) normal version of the symbol over the (also compiled) weak version of the symbol. Linking happens after compilation.
why this happens.
You have written a #warning in your code and it's going to be visible and processed by the compiler anyway, irrelevant if the function is used or not. #warnings are interpreted by the preprocessor, before compilation.
How to force user implement __weak functions
First, do not use weak in header file. It would make all function definitions weak that see this declaration.
// header
void checkButtons();
Secondly, if you want to force user to define the function, then don't use weak and don't define the function. Weak symbols are used when you want to provide a default definition for the function, if you don't want to do it then don't use it. Without function definition, user will receive a "undefined reference"-kind-of error message from the linker.
I'm writing a library and have some functions which need to be overwritten by the programmers
Yet better and normal way would be for your library to take function pointers that point to the functions implemented by the user of your library. Such design is "better" - allows code reuse, easier unit-testing and saves a lot of refactoring in case of later changes.
I need a symbol alias to be the alias for the function function as described in this question, but for IAR compiler/linker. I have tried answers for GCC, but those don't work, obviously:
// source code
void alias(void) __attribute__ ((alias ("function")));
Error[Pe130]: expected a "{" C:\project\test.c 61
void alias(void) asm("function");
Error[Pe065]: expected a ";" C:\project\test.c 61
#pragma weak alias=function
Error[e46]: Undefined external "alias" referred in ?ABS_ENTRY_MOD ( )
// linker options:
-Dalias=function
Fatal Error[e163]: The command line symbol "function" in -Dalias=function is not defined.
Does anyone know how I can define a function alias in IAR/Xlink?
A little background: I'm responsible for a module which is used in several projects. In order to test it, I have developed test cases for testIDEA tool which validate assertions at certain breakpoints. However, some common functions have different names in different projects (e.g. the initialization function could be called init(), init_mcu(), startup() etc.) so every time my module is integrated in a new project, I have to modify my test cases to match the new function names. What I'd like to do instead is to define a common alias (e.g. test_init()) to whatever the init function is called, so that my test cases can always set a breakpoint using this common name. I expect this symbol to make it to the ELF file, where it can be seen by the debugger.
From the IAR C/C++ Development Guide (p. 258):
To make the definition of foo a weak definition, write:
#pragma weak foo
To make NMI_Handler a weak alias for Default_Handler, write:
#pragma weak NMI_Handler=Default_Handler
If NMI_Handler is not defined elsewhere in the program, all references to NMI_Handler will refer to Default_Handler.
So, try something like this:
void f1(void);
void f2(void);
#pragma weak f1=f2
void f2(void) {}
After a close look at xlink options I've found the one which sort of suits my needs:
-e -enew=old [,old] …
Use -e to configure a program at link time by redirecting a function call from one function to another.
This can also be used for creating stub functions; i.e. when a system is not yet complete, undefined function calls can be directed to a dummy routine until the real function has been written.
I ended up with this code:
void alias(void) {
// copy the body of function()
}
// Linker parameters
-ealias=function
This redirects all calls to function() to alias(), regardless the actual name function has. Sure it's an ugly hack because I have to copy the code, but I get what I wanted: I can set a breakpoint to alias() by name.
Wikipedia says:
A weak symbol denotes a specially annotated symbol during linking of
Executable and Linkable Format (ELF) object files. By default, without
any annotation, a symbol in an object file is strong. During linking,
a strong symbol can override a weak symbol of the same name. In
contrast, two strong symbols that share a name yield a link error
during link-time. When linking a binary executable, a weakly declared
symbol does not need a definition. In comparison, (by default) a
declared strong symbol without a definition triggers an undefined
symbol link error. Weak symbols are not mentioned by C or C++ language
standards; as such, inserting them into code is not very portable.
Even if two platforms support the same or similar syntax for marking
symbols as weak, the semantics may differ in subtle points, e.g.
whether weak symbols during dynamic linking at runtime lose their
semantics or not.
What are the weak functions and what are their uses? I am using an stm32f429 micro controller. There are some weak functions in the library. But I can't understand, what they and their use!
I searched about it on google but did't get a satisfactory answer.
When a function is prepended with the descriptor __weak it basically means that if you (the coder) do not define it, it is defined here.
Let us take a look at my arch-nemesis "HAL_UART_RxCpltCallback()".
This function exists within the HAL of the STM32F4-HAL code base that you can download from ST-Micro.
Within the file stm32f4xx_hal_uart.c file you will find this function defined as:
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
}
So, as the note within the code here says, place this function inside your own user files. However when you do that, do not put in the __weak term. This means that the linker will take your definition of the HAL_UART_RxCpltCallback() function and not the one defined within the stm32f4xx_hal_uart.c file.
This gives the generic code base the ability to always compile. You don't have to write a whole bunch of functions that you are not interested in but it will compile. When it comes time to writing your own, you just have to NOT define yours as __weak and write it.
Simple? Helpful?
Cheers!!
Let's say we have a common (library) protocol interface protocol.c, and upon receiving data we wish to execute application specific logic in our communication interface com.c. This can be solved with a weak function.
/// protocol.h
void protocol_recCallback(protocol_t *prt);
/// protocol.c
__weak void protocol_recCallback(protocol_t *prt) {}
void protocol_rx(protocol_t *prt)
{
// Common protocol interface
protocol_recCallback(prt); // This will call application specific function in com.c
}
/// com.c
#include "protocol.h"
void protocol_recCallback(protocol_t *prt)
{
// Application specific code is executed here
}
Advantage:
If protocol_recCallback() is not defined in com.c. The linker will not output an undefined reference and the __weak function will be called.
__weak function are methods that can be overwritten by user function with same name, used to define vector tables, and default handlers
Normal function writing (declaration and definition) are considered strong meaning that the function name cannot be re declared, you will get compiler/linker error
Declaring the function as week it can be overwritten by user code
void USART1_IRQHandler (void) __attribute__ ((weak, alias("Default_Handler")));
uint32_t vectors[75] __attribute__((section(".isr_vector")));
vectors[0] = STACK_START;
vectors[52] = USART1_IRQHandler;
void Default_Handler(void) {
while(1);
}
uart1.c (user code)
void USART1_IRQHandler(){
...
}
in the above sample code the USART1_IRQHandler is defined as weak function and aliased to Default_handler
User can override this function using the same name without any compiler/linker error if user define the USART1_IRQHandler in uart1.c this new function definition will be used
In addition to "This gives the generic code base the ability to always compile." __weak allows you to regenerating(in CubeMX) your code without touching your __weak +less callback function code.
if you write your code in this:
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* NOTE: This function Should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
}
and regenarate in cubemx for some reason. Your code will blow up!
Please don't redirect me to there answers here - I have read them, and other answers all over the internet, including the standard, but am still confused (mostly, I think because of the overlap of technical words, english words, and language keywords).
Let me get this straight, in C99, for functions:
static: Don't produce any external symbols
extern (implicit): If there are no definitions in this translation unit, the compiler produces a reference that is resolved during linking
Now with inline. As far as I can tell, the issue is complicated due to the fact that the compiler may choose to inline, or not.
If the compiler decides to inline, clearly the implementation must be visible at compile-time
If the compiler decides not to inline, what function gets linked, and in which translation unit does that code live?
I can see this being answered in two different ways:
If a compiler decides not to inline a function at some call site, then non-inline object code is generated inside the same translation unit. No external symbols are exported for this.
If a compiler decides not to inline a function at some call site, then this behaves as a normal function, and there must be one translation unit that exports an external symbol and contains object code implemnitating the function.
static inline seems to be the answer to #1:
If the compiler decides to inline a static inline function, then go for it. The static storage specifier is consistent with it's use with non-inline functions in that no external symbols are produced. Since this is the case, if the compiler decides to inline a static inline function at every call site within a translation unit, it need not generate stand-alone object code.
If the compiler decides not to inline a static inline function at some call site, then it can generate stand-alone object code inside the translation unit, and no external symbols will be exported for it.
As far as I can tell, extern inline/inline is the answer to #2:
All inline (without extern or static) behave like #2. If the compiler doesn't actually inline them, then at link time an external implementation needs to be linked-in.
The translation unit that actually exports a symbol to link against
must declare as extern inline. I think this is what's most
confusing, since the extern keyword for normal functions behaves in
almost the exact opposite way
Is this correct?
Relevant links, yet still leave fuzzy corners:
Is “inline” without “static” or “extern” ever useful in C99?
extern inline
The New C: Inline Functions
Your overall understanding of this is correct.
The translation unit that actually exports a symbol to link against must declare as extern inline. I think this is what's most confusing, since the extern keyword for normal functions behaves in almost the exact opposite way
Yes, this is an unfortunate part of the language, but you have the right of it.
As a minor bit of trivia (which hopefully does not confuse you), GNU gcc used to treat "inline" and "extern inline" exactly opposite the way that the C99/C11 standard treats them. In this case, GNU would interpret "inline" as "use this definition to inline with AND produce the out-of-line, externally visible definition of this function" and it would treat "extern inline" as "only use this definition for inlining; if inlining does not occur, then emit an extern reference to the function (which must be defined elsewhere)".
For whatever reason the C99 standard chose to swap meaning of "inline" and "extern inline" and now we are stuck with it.
Note: Quick testing shows that GNU gcc v4.9.2 will default to the "GNU" way (-fgnu89-inline) if you don't otherwise pass -std=c99/c11 or -fno-gnu89-inline. Sometime between then and GNU gcc v5.2.1 it changed because v5.2.1 will default to -fno-gnu89-inline (i.e. the standard C99/C11 way).