Ir ao conteúdo
  • Cadastre-se

C++ Como usar __attribute__((weak)) para testar se a função foi definida?


Cambalinho

Posts recomendados

como usar '__attribute__((weak))'?

#include <iostream>
#define  event __attribute__((weak))
  
using namespace std;

class test2
{
public:
   void Hello() event;
    void hey()
    {
        if(&Hello==NULL) Hello();
    }

};

/*void test2::Hello()
{
    cout << "hello world!!!";
}*/

test2 a;
int main()
{
    a.hey();

    return 0;
}

ao executar tenho 1 erro:

"Process returned -1073741819 (0xC0000005)   execution time : 0.680 s
Press any key to continue."

o erro está nesta linha que estou a tentar corrigir:

if(&Hello==NULL) Hello();

como se usa o __attribute__((weak)) para testar se a função foi definida?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Essa linha,

 

Em 14/11/2023 às 13:05, Cambalinho disse:
if(&Hello==NULL) Hello();

 

não faz o menor sentido. Talvez, o que busca seja um ponteiro pra uma função como membro de test2. Ou seja,

 

class test2 {
    public:
    test2(): Hello(NULL) {}

    void (*Hello)();

    void hey() {
        if (this->Hello != NULL) this->Hello();
    }
};

 

Agora, basta associar uma função com a mesma assinatura de Hello pro membro this->Hello. P/ex:

 

void Hi() {
    cout << "hello world!!!\n";
}

test2 a;
int main() {
    a.Hello = Hi;
    a.hey();

    return 0;
}

 

  • Curtir 1
  • Amei 1
Link para o comentário
Compartilhar em outros sites

30 minutos atrás, V!OLADOR disse:

não faz o menor sentido. Talvez, o que busca seja um ponteiro pra uma função como membro de test2

 

Faz sentido de algum modo. Uma weak reference é isso: pode ser NULL. Mas o modo de testar é que não faz sentido. Quem testa pela referência ser NULL é o linker e não o runtime. weak references são um tipo folclórico de override.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...
Em 14/11/2023 às 18:05, Cambalinho disse:

o erro está nesta linha que estou a tentar corrigir:

if(&Hello==NULL) Hello();

como se usa o __attribute__((weak)) para testar se a função foi definida?

 

Em 15/11/2023 às 23:57, V!OLADOR disse:

Talvez, o que busca seja um ponteiro pra uma função como membro de test2. Ou seja,

 

class test2 {
    public:
    test2(): Hello(NULL) {}

    void (*Hello)();

    void hey() {
        if (this->Hello != NULL) this->Hello();
    }
};

 

Agora, basta associar uma função com a mesma assinatura de Hello pro membro this->Hello

 

Em 16/11/2023 às 00:30, arfneto disse:

Uma weak reference é isso: pode ser NULL. Mas o modo de testar é que não faz sentido. Quem testa pela referência ser NULL é o linker e não o runtime. weak references são um tipo folclórico de override

 

Então vou deixar um exemplo aqui. Como eu disse, esse atributo é para o link e não para tempo de execução. Se pode ter referências fortes ou fracas para um símbolo, strong refererences ou weak references. Se pode ter no máximo uma strong reference, ou o linker vai reclamar de símbolo duplicado. Mas se pode ter qualquer número de referências fracas e aĩ vale a última que o linker encontrar.

 

Como usar um 🚃 desses? Considere esse programa main.cpp

 

#include <iostream>
using std::cerr;

int fa() __attribute__((weak));
int fb() __attribute__((weak));
int fc() __attribute__((weak));

int main(void)
{
    cerr << ".....main\n";
    fa(), fb(), fc();
    return 0;
}

int fa()
{
    cerr << ".....fa ainda não foi implementada\n";
    return 0;
};

int fb()
{
    cerr << ".....fb ainda não foi implementada\n";
    return 0;
};

int fc()
{
    cerr << ".....fc ainda não foi implementada\n";
    return 0;
};

 

Então tem essas 3 funções, fa fb e fc, todas marcadas como weak references.

 

Rodando isso:

 

arfneto@Linux42:~/Documents/project1$ g++ -o x --std=c++2a -Wall main.cpp
arfneto@Linux42:~/Documents/project1$ ./x
.....main
.....fa ainda não foi implementada
.....fb ainda não foi implementada
.....fc ainda não foi implementada

 

Como são weak references, qualquer dessas funções pode ser incluída de novo a partir de outra unidade de compilação (arquivo) sem erro. 

 

Considere fa.cpp

 

#include <iostream>
using std::cerr;

int fa()
{
    std::cerr << ".....fa esta presente!\n";
    return 0;
};

 

E eis o que acontece

 

arfneto@Linux42:~/Documents/project1$ g++ -o x --std=c++2a -Wall main.cpp fa.cpp
arfneto@Linux42:~/Documents/project1$ ./x
.....main
.....fa esta presente!
.....fb ainda não foi implementada
.....fc ainda não foi implementada

 

É assim que se usa.

 

Considere outrofa.cpp

 

#include <iostream>
using std::cerr;

int fa()
{
    std::cerr << ".....outra fa esta presente!\n";
    return 0;
};

 

E tentando usar as duas:

 

arfneto@Linux42:~/Documents/project1$ g++ -o x --std=c++2a -Wall main.cpp fa.cpp outrofa.cpp
/usr/bin/ld: /tmp/ccg0pS1X.o: in function `fa()':
outrofa.cpp:(.text+0x0): multiple definition of `fa()'; /tmp/ccLgz9ie.o:fa.cpp:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
arfneto@Linux42:~/Documents/project1$ 

 

Acho que assim fica mais claro o que eu queria dizer com ser um tipo de override.

 

E que nada tem a ver com runtime.

 

Se em fa.cpp fa() tambem fosse uma weak reference isso ia rodar

 

arfneto@Linux42:~/Documents/project1$ g++ -o x --std=c++2a -Wall main.cpp fa.cpp outrofa.cpp
arfneto@Linux42:~/Documents/project1$ ./x
.....main
.....outra fa esta presente!
.....fb ainda não foi implementada
.....fc ainda não foi implementada
arfneto@Linux42:~/Documents/project1$

 

E a strong reference em outrofa.cpp  iria se sobrepor às duas declarações anteriores de fa()

 

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

1 hora atrás, Cambalinho disse:

sei que posso usar variáveis de funções... mas é(é o meu objetivo principal) possível testar se a função foi definida ou não?

 

Não entendo o quer quer dizer com isso. Te mostrei um exemplo de como usar weak references exatamente para isso. Em link time.

 

Em tempo de compilação o compilador faz isso. 

 

Em tempo de execução se pode usar ponteiros para funções ou vetores de ponteiros para funções --- VFT no popular.  

 

Qual é seu "objetivo principal"  então?

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

eu percebi mal alguma coisa.. desculpe:

#include <iostream>

using namespace std;

class test2
{
    public:

    void (*Hello)();

    void hey()
    {
        if (this->Hello != NULL) this->Hello();
    }
};

void test2::Hello()
{
    cout << "hello";
}

int main()
{
    test2::Hello();
    cin.get();
    return 0;
}

tenho 1 erro na linha: 

void test2::Hello()

"error: cannot declare pointer to 'void' member"

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

22 horas atrás, Cambalinho disse:

então fico com a questão: sei que posso usar variáveis de funções... mas é(é o meu objetivo principal) possível testar se a função foi definida ou não?

 

Você perguntou "como usar __attribute__((weak)) para testar se a função foi definida?" só que esse não era seu objetivo principal? ok ok ok 🙂  

 

Você também falou em "função não definida"  e depois em " função não implementada"...

 

Deve ser (muito) mais formal em relação a essas coisas.

 

Em tempo de compilação o compilador vai te dizer se uma função está ou não definida.

 

Em link time pode usar atributos como eu te expliquei. Há algo parecido para Microsoft mas não igual. Veja por exemplo https://devblogs.microsoft.com/oldnewthing/20200731-00/?p=104024 e tem outras opções

 

Em tempo de execução isso não existe.

 

Quanto a isso

 

class test2
{
    public:

    void (*Hello)();

    void hey()
    {
        if (this->Hello != NULL) this->Hello();
    }
};

void test2::Hello()
{
    cout << "hello";
}

 

Só está errado mesmo. Declarou Hello duas vezes. Como acha que vai funcionar?

 

Declarou mas não inicializou. Recomendo não fazer isso. E está confundindo instância com classe. Não pode chamar a função a partir de uma classe...

 

Isso funciona:

 

#include <iostream>
using namespace std;

void  Hi()
{
    cout << "hi!\n";
}


class test2
{
public:

    void (*Hello)() = nullptr;

    void hey()
    {
        if (Hello != nullptr) Hello();
        else {
            cerr << "Sem funcao\n";
            Hello = Hi;
        }
    }
};


int main()
{
    test2 algum;
    algum.hey();
    algum.hey();
    return 0;
}
  

 

Porque também está considerando funções membro como funções comuns. Não são.

 

E mostra

 

Sem funcao
hi!

 

Isso funciona também:

 

#include <iostream>
using std::cerr;

int fa();
int fb();
int fc();
void tf(int(*f)());

int main(void)
{
    int(*funcao)() = nullptr;
    tf(funcao);

    funcao = fa, tf(funcao);
    funcao = fb, tf(funcao);
    funcao = fc, tf(funcao);
    // volta para nullptr
    funcao = nullptr, tf(funcao);
    return 0;
}

int fa()
{
    cerr << ".....Usando fa()\n";
    return 0;
};

int fb()
{
    cerr << ".....Usando fb()\n";
    return 0;
};

int fc()
{
    cerr << ".....Usando fc()\n";
    return 0;
}
void tf(int(*f)())
{
    if (f == nullptr)
        cerr << ".....funcao não definida\n";
    else
        f();
};
  

 

E é um modo comum de escrever

 

Mostra

 

.....funcao não definida
.....Usando fa()
.....Usando fb()
.....Usando fc()
.....funcao não definida

 

 

 

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

  • Simon Viegas alterou o título para Como usar __attribute__((weak)) para testar se a função foi definida?

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!