g ++ определяемые пользователем глобальные операторы new и delete для динамически связанных библиотек - PullRequest
0 голосов
/ 17 февраля 2020

На g ++ код из динамически связанных библиотек использует оператор delete из основной программы. С опцией -Wl,-Bsymbolic динамически связанная библиотека использовала свой собственный оператор new, но использует оператор delete основной программы. Компиляция с использованием clang ++ с опцией -Wl,-Bsymbolic имеет динамически связанную библиотеку с использованием собственного оператора new и delete. На linux (ubuntu)

// base_program.cpp
#include <dlfcn.h>
#include <stdio.h>
#include <cstdlib>
typedef void dllFunc();

void *operator new(std::size_t count) {
    printf("base_program new\n");
    void *result = malloc(count);
    return result;
}
void *operator new[](std::size_t count) {
    printf("base_program new[]\n");
    void *result = malloc(count);
    return result;
}
void operator delete(void *ptr) noexcept {
    printf("base_program delete\n");
    free(ptr);
}
void operator delete[](void *ptr) noexcept {
    printf("base_program delete[]\n");
    free(ptr);
}

int main(int nArgs, char **args) {
    void *handle = dlopen(DLLFILE, RTLD_LAZY);
    dllFunc *func = (dllFunc*) dlsym(handle, "testFunc");
    printf("Linking with %s\n", DLLFILE);
    int *a = new int;
    delete a;
    func();
    printf("\n");
    return 0;
}
// linking.cpp
#include <stdio.h>
#include <cstdlib>
void *operator new(std::size_t count) {
    printf("linking new\n");
    void *result = malloc(count);
    return result;
}
void *operator new[](std::size_t count) {
    printf("linking new[]\n");
    void *result = malloc(count);
    return result;
}
void operator delete(void *ptr) noexcept {
    printf("linking delete\n");
    free(ptr);
}
void operator delete[](void *ptr) noexcept {
    printf("linking delete[]\n");
    free(ptr);
}

extern "C" void testFunc() {
    int *a = new int;
    delete a;
}
// build.sh
g++ -g -fPIC -DDLLFILE="\"linking_g.so\"" base_program.cpp -o base_program_g -ldl
g++ -g -fPIC -shared linking.cpp -o linking_g.so -Wl,-Bsymbolic

clang++ -g -fPIC -DDLLFILE="\"linking_clang.so\"" base_program.cpp -o base_program_clang -ldl
clang++ -g -fPIC -shared linking.cpp -o linking_clang.so -Wl,-Bsymbolic

Запуск ./build.sh; ./base_program_g; ./base_program_clang приводит к следующему

Linking with linking_g.so
base_program new
base_program delete
linking new
base_program delete

Linking with linking_clang.so
base_program new
base_program delete
linking new
linking delete


Как мне получить поведение clang ++ в g ++?

1 Ответ

0 голосов
/ 17 февраля 2020

operator delete имеет разные объявления в разных стандартах C ++. Для ваших определений с noexcept требуется C ++ 11.

Возможно, вы используете старую версию g++, которая по умолчанию компилируется в диалект C ++ 03.

Исправление заключается в явной установке C ++ 11 или более новый стандарт в командной строке. Я протестировал с -std=gnu++11, и это исправляет вашу проблему.

...