C++ qual usar: NULL ou 0 ou nullptr? [RESOLVIDO]

1. C++ qual usar: NULL ou 0 ou nullptr? [RESOLVIDO]

Samuel Leonardo
SamL

(usa XUbuntu)

Enviado em 01/05/2016 - 14:48h

FIquei em dúvida quando tava conversando com um amigo. Ele queria iniciar um ponteiro com NULL, dai eu falei que deveria usar 0 ou nullptr como valor de inicialização.
Então, fiquei em duvida, pois não tenho costume de usar NULL e nem nullptr em C++, uso sempre 0 como valor para ponteiro.
Alguém sabe me dizer as diferenças e qual dos 3 devo usar? Se é que não os 3 juntos, um tanto faz.


  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/05/2016 - 20:22h

Em C não há dúvida: use NULL. Esse símbolo, definido em <stddef.h>, tem o valor de um ponteiro nulo e o tipo void *, que funciona mais ou menos com “ponteiro para qualquer tipo”.


Usar o valor inteiro zero era a abordagem preferida pelo C++ antes do padrão de 2011 (e também era a do C antes do padrão de 1989, que introduziu void, void * e padronizou a constante NULL).

O sistema de tipos do C++ trata void * do modo diferente do C. Em vez do sentido de ponteiro para qualquer tipo de dado, o sentido é mais como o de ponteiro para dado de tipo indeterminado. Pode-se fazer com que o ponteiro desses aponte para um dado de tipo conhecido, mas o reverso requer muito mais cuidado. Veja:

char *pc;
int *pi;
void *pv;

pc=strdup("Teste");
pv=pc; // OK em C e C++.
pc=pv; // OK em C, erro em C++.
pi=pv; // OK em C, erro em C++.
free(pc);


Além de atribuições diretas como as acima, C++ tem outro aspecto, inexistente em C, que reforça a necessidade de cuidado com conversão de tipos, que são dois modos de polimorfismo suportado pela linguagem, ambos ligados aos tipos de dados que lhes servem de parâmetros (a saber: a sobrecarga de funções e programação genérica).

E acredito (não li isso em lugar nenhum -- é minha interpretação pessoal, mesmo) que a opção de usar a constante zero em vez de conversões automáticas de um tipo de ponteiro padrão foi uma solução de compromisso: o usuário se livrava de algumas surpresas referentes à conversão automática (ou da falta delas) entre ponteiros, mas podia acabar encontrando outras, por conta da do uso de funções ou objetos parametrizados com inteiros, quando ele talvez esperasse parâmetros ponteiros. Veja abaixo.

// Código em C++98
#include <cstddef> // define NULL, que em C++ é “0” (e não “(void *)0”, como é em C).

void f(char *pc){ /* ... Usa pc. ... */ }
void f(int i){ /* ... Usa i. ... */ }

void g(void *pv){ /* ... Usa pv. ... */ }
void g(int i){ /* ... Usa i. ... */ }

void h(){
char *pc;
void *pv;
int *pi;

pc=0; // OK: pc é um ponteiro para char com valor nulo.
pc=NULL; // OK (em C++, NULL é 0; em C, é ((void *)0)).
pc=(void *)0; // ERRO: tipo de ponteiro incompatível (mesmo sendo o valor nulo).
f(NULL); // OK, mas chama f(int), não f(char *).
f(pc); // OK: chama f(char *);

pv=pc; // OK: conversão para void * é permitida.
pc=pv; // ERRO: tipo de ponteiro incompatível (em C seria permitido).
f(pv); // ERRO: tipo de ponteiro incompatível.
g(pv); // OK: chama g(void *).
g(pc); // OK: chama g(void *).
g(NULL); // OK, mas chama g(int).

pc=(char *)pv; // OK, mas obsoleto.
pc=static_cast<char *>(pv); // OK, desde que pv seja um void * (é o caso).

pi=static_cast<int *>(pv); // OK.
pc=(void *)pi; // OK, mas obsoleto e perigoso.
pc=static_cast<char *>(pi); // ERRO: tipo incompatível.
pc=reinterpret_cast<char *>(pi); // OK: você está dizendo que assume o risco.
}


O tipo std::nullptr_t foi introduzido no C++11, juntamente com a nova palavra-chave nullptr. nullptr é o único valor válido do tipo std::nullptr_t. Este, por sua vez, é um tipo distinto de qualquer ponteiro e também de qualquer inteiro, mas permite conversão automática para qualquer ponteiro e também para booleano (tipo bool).

O artigo sobre o C++11 na Wikipedia (em Inglês) é muito bom, e tem uma seção sobre nullptr. Os cppreference.com também tem uma boa descrição.

3. Re: C++ qual usar: NULL ou 0 ou nullptr? [RESOLVIDO]

Uilian Ries
uilianries

(usa Linux Mint)

Enviado em 02/05/2016 - 08:03h

Para C++, utilize nullptr sempre que possível.

nullptr é tipo bem definido, diferente de apenas usar 0.

O comitê do C++ reforça este uso, no principal e mais atual guia de boas práticas:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-nullptr

Compiladores gcc-4.6, clang 2.9 e msvc-10.0 já supportam esta feature do C++11.
Para os compiladores gcc e clang, basta adicionar a opção --std=c++11

g++ main.cpp -o Exemplo -std=c++11







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner
Linux banner
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts