Fundamentals 9 min read

Mastering Strong and Weak Functions in C for Flexible Embedded Design

This article explains the concept of strong and weak functions in C, shows how to declare them with GCC and other compilers, outlines the linker selection rules, and demonstrates practical uses such as library overrides, interrupt handlers, callbacks, test stubs, plugin systems, and related pitfalls.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Mastering Strong and Weak Functions in C for Flexible Embedded Design

Basic Concepts

In C programming, strong and weak functions form a priority mechanism used by the linker when multiple definitions of the same symbol exist. A strong function always overrides a weak one, ensuring the linker picks the intended implementation.

Strong Function

// Strong function example
void my_function(void)
{
    printf("This is a strong function implementation
");
}

Weak Function

A weak function provides a default implementation that can be replaced by a strong definition. In GCC it is declared with __attribute__((weak)):

// Weak function example
void __attribute__((weak)) my_function(void)
{
    printf("This is a weak function implementation
");
}

Declaration Methods

GCC Weak Declaration

// Method 1: attribute on definition
void __attribute__((weak)) weak_func(void)
{
    // default implementation
}

// Method 2: separate declaration and definition
void weak_func(void) __attribute__((weak));
void weak_func(void)
{
    // default implementation
}

Other Compilers

IAR : #pragma weak weak_func ARMCC :

__weak void weak_func(void) { /* ... */ }

Linker Rules

If only one definition (strong or weak) exists, it is used.

Multiple strong definitions cause a duplicate‑symbol error.

If a strong and one or more weak definitions exist, the strong one is selected.

If only weak definitions exist, the first encountered weak symbol is chosen (often with a warning).

Typical Applications

Library Function Redefinition

// Library provides a weak default
void __attribute__((weak)) library_func(void)
{
    // default implementation
}

// User can override
void library_func(void)
{
    // custom implementation
}

Interrupt Handling in Embedded Systems

// Default weak ISR
void __attribute__((weak)) TIMER1_IRQHandler(void)
{
    while(1); // trap
}

// User‑provided ISR
void TIMER1_IRQHandler(void)
{
    // actual handling code
}

Default Callback Implementation

// Framework provides a weak callback
void __attribute__((weak)) on_data_received(int data)
{
    // does nothing by default
}

void process_data(int data)
{
    // ...process...
    on_data_received(data);
}

// Application can implement the callback
void on_data_received(int data)
{
    printf("Received: %d
", data);
}

Test Stub Functions

// Production code (weak)
int __attribute__((weak)) read_sensor(void)
{
    return hardware_read_sensor();
}

// Test code (strong)
int read_sensor(void)
{
    return mock_value; // simulated value
}

Checking Whether a Weak Function Was Overridden

extern void __attribute__((weak)) weak_func(void);

if (weak_func) {
    // overridden – call it
    weak_func();
} else {
    // use default behavior
}

Weak Symbols for Variables

int __attribute__((weak)) weak_var = 10;
int strong_var = 20; // strong symbol

Multiple Weak Functions

// file1.c
void __attribute__((weak)) func() { printf("Weak 1
"); }

// file2.c
void __attribute__((weak)) func() { printf("Weak 2
"); }

// Link order decides which implementation is used

Important Considerations

Portability: strong/weak functions are compiler extensions, not part of the C standard.

Debugging: overridden functions can make call‑stack tracing harder.

Performance: indirect calls through weak symbols may add a tiny overhead.

Naming conflicts: careless use can lead to hard‑to‑detect symbol clashes.

Initialization order: global constructors that rely on weak functions must consider startup sequencing.

Real‑World Cases

UART Driver

// Library supplies a weak init
void __attribute__((weak)) UART_Init(void)
{
    // default init code
}

// Application provides hardware‑specific init
void UART_Init(void)
{
    USART1->BRR = 0x341;
    // …more setup…
}

Plugin System Design

// Core framework (weak hooks)
void __attribute__((weak)) plugin_init(void) {}
void __attribute__((weak)) plugin_process(int data) {}

void framework_run(void)
{
    plugin_init();
    while (1) {
        int data = get_data();
        plugin_process(data);
    }
}

// Plugin implementation
void plugin_init(void)
{
    printf("Plugin loaded
");
}

void plugin_process(int data)
{
    printf("Processing data: %d
", data);
}

Weak Functions with Function Pointers

void __attribute__((weak)) default_handler(int);

void (*handler)(int) = default_handler;

void process_event(int event)
{
    if (handler) handler(event);
}

// User can replace the handler
void default_handler(int event)
{
    printf("Default handling: %d
", event);
}

Conclusion

Strong and weak functions are a powerful C feature, especially useful in system‑level and embedded development. They enable libraries to provide default behavior while allowing users to supply custom implementations, support modular and plugin architectures, simplify unit testing, and improve code flexibility. However, developers must be aware of their compiler‑specific nature, potential debugging complexity, and naming‑conflict risks.

Original source: https://blog.csdn.net/absurd/article/details/622055
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Csoftware designembeddedgccLinkerstrong functionweak function
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.