Quando o ponteiro nulo não é inválido

Data: 2008-02-29
Categorias: C++

Coding HorrorExiste coisa mais prazerosa do que admitir um erro que foi cometido na mesma semana? Existe: quando você sabia que estava certo, mas resolveu usar o senso comum por falta de provas.

Pois bem. O mesmo amigo que me recomendou que escrevesse sobre o assunto do ponteiro nulo achou um livro sobre armadilhas em C com um exemplo que demonstra exatamente o contrário: dependendo da plataforma, ponteiros nulos são sim válidos.

Nesse caso, se tratava de um programa que iria rodar em um microprocessador, daqueles que o DQ costuma programar. Pois bem. Quando o dito cujo ligava era necessário chamar uma rotina que estava localizada exatamente no endereço 0. Para fazer isso, o código era o seguinte:

( * (void(*)()) 0 ) ();

Nada mais simples: um cast do endereço 0 (apesar de normalmente inválido, 0 pode ser convertido para endereço) para ponteiro de função que não recebe parâmetros e não retorna nada, seguido de deferência ("o apontado de") e chamada (a dupla final de parênteses).

(* (void(*)()) 0 ) ();

É bem o que o autor diz depois de jogar esta expressão: "expressions like these strike terror into the hearts of C programmers". É lógico que isso não é bem verdade para as pessoas que acompanham este blogue =)

7 respostas para “Quando o ponteiro nulo não é inválido”

  1. Bleno Diz:

    Olá Caloni...
    Bom post... Parabéns pelo site. Ótimo material...
    Ah, no link do blog do http://dqsoft.blogspot.com/ está faltando o "g" de bloGspot ;)

    Abraços...
    []´s

  2. Daniel Quadros Diz:

    Bem que eu ia colocar um comentário a respeito... Na programação "embarcada" é comum aparecerem alguns endereços fixos. Por exemplo, em um microcontrolador que estou programando a gravação na memória não volátil é feita colocando-se os dados de um "setor" na Ram a partir do endereço zero e depois "dançando um samba" sobre alguns registradores. Para o código ficar um pouco mais bonito, declarei o buffer de gravação em um módulo assembler e evitei ter um ponteiro explicitamente nulo.

  3. Alberto Fabiano Diz:

    Este livro do Koening é realmente uma obra muito interessante; eu também recomendo! Aliás, ele é considerando uma das 10 personalidades mais importantes do C++ e está na lista do 5 mais do Scott Meyers.

  4. Yorick Diz:

    Gostaria de aproveitar e mencionar Walter Oney

    More About NULL Pointers:

    While we’re on the subject of invalid pointers, note that a NULL pointer is (a) an invalid user-mode
    pointer in Windows XP and (b) a perfectly valid pointer in Windows 98/Me. If you use a NULL
    pointer directly, as in *p, or indirectly, as in p->StructureMember, you’ll be trying to reference
    something in the first few bytes of virtual memory. Doing so in Windows XP will cause a trappable
    access violation.
    Dereferencing a NULL pointer in Windows 98/Me will not, of itself, cause any immediately
    observable problem. I once spent several days tracking down a bug that resulted from overstoring
    location 0x0000000C in a Windows 95 system. That location is the real-mode vector for the
    breakpoint (INT 3) interrupt. The wild store didn’t show up until some infrequently used
    application did an INT 3 that wasn’t caught by a debugger. The system reflected the interrupt to
    real mode. The invalid interrupt vector pointed to memory containing a bunch of technically valid
    but nonsensical instructions followed by an invalid one. The system halted with an invalid operation
    exception. As you can see, the eventual symptom was very far removed in space and time from the
    wild store.

  5. Wanderley Caloni Diz:

    Olá, Bleno. Valeu pela dica! Corrigido.

  6. Wanderley Caloni Diz:

    Olá, Yorick.

    Desconhecia esse comentário do Walter. Provavelmente é bem antigo, já que ele está citando Win9x, um tabu atualmente entre o pessoal da MS.

    Também desconhecia esse detalhe de implementação desses sitemas. Valeu a dica!

    []s

  7. Caloni.com.br » Blog Archive » Try-catch flutuante Diz:

    [...] detalhe da linguagem quem me fez descobrir foi o Yorick, que costuma comentar no blogue e tive o prazer de conhecer no 4o. [...]

Deixe uma resposta