Указатель на функцию или атрибут weak?

Указатель на функцию и атрибут weak представляют два различных концепта в языке программирования C.

Указатель на функцию позволяет хранить адрес функции. Это позволяет программисту вызывать функцию через указатель, что может быть полезно в абстрактных обработчиках событий, паттернах проектирования или при использовании функций обратного вызова. Указатель на функцию имеет специальный тип, совпадающий с прототипом функции, на которую он указывает. Это позволяет проверять типы аргументов и возвращаемого значения функции, чтобы избежать ошибок времени выполнения. Пример использования указателя на функцию:

#include <stdio.h>

// функция, на которую будет указывать указатель
void print_message(const char* message) {
    printf("%sn", message);
}

int main() {
    void (*function_ptr)(const char*); // объявление указателя на функцию
    function_ptr = &print_message; // присваивание адреса функции указателю
    function_ptr("Hello, World!"); // вызов функции через указатель
    return 0;
}

Атрибут weak позволяет указать, что переменная или функция являются слабыми (weak). Переменная или функция с атрибутом weak может быть переопределена в другом месте программы, исключая ошибки компоновщика при наличии нескольких определений. Атрибут weak полезен в случаях, когда программист хочет заменить функцию или переменную в другом модуле программы, например, для создания плагинов или модульных тестов.

Пример использования атрибута weak:

#include <stdio.h>

// объявление функции с атрибутом weak
void __attribute__((weak)) print_message(const char* message) {
    printf("%sn", message);
}

int main() {
    // вызов функции, которая может быть переопределена в другом месте программы
    print_message("Hello, World!");
    return 0;
}

Таким образом, указатель на функцию и атрибут weak представляют разные концепции в языке C, которые могут быть использованы для разных целей. Указатель на функцию позволяет вызывать функцию через указатель, а атрибут weak позволяет переопределить функцию или переменную в другом модуле программы.