Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

268
Visualizações
¿Por qué el puntero implícito de la conversión de puntero a puntero es legal?

Recientemente encontré un código en stackoverflow donde los punteros a los punteros se usaban para cambiar la memoria asignada. Mientras revisaba el código, cometí el error de agregar un ampersand a un puntero, así que haga un puntero a un puntero, pero el compilador compiló felizmente y se produjeron errores de tiempo de ejecución. Como ejemplo

 #include <stdio.h> void func(int **p) { printf("Pointer is at %p\n", p); } int main(void) { int *p = 0; func(p); func(&p); int **pp = &p; func(&pp); return 0; }

Entiendo que C tiene restricciones significativamente más bajas para punteros que C++ y permite algo como char *buf = malloc(SIZE) mientras que C++ no está permitido. Lo veo como una conveniencia porque sucede mucho en C.

Sin embargo, creo que la cantidad de referencias es una gran fuente de errores y me pregunto por qué se podría permitir esto, especialmente porque int es diferente de int* . Además, quiero saber si el estándar C dice algo al respecto.

EDITAR Lo compilé en ideone.com, que probablemente no muestre advertencias. Mi compilador clang local, así como gcc, dan advertencias. Aún así, ¿por qué son solo advertencias cuando representan cosas diferentes?


PD: Siento que algo como esto debería haberse preguntado en los últimos seis años de SO. Si se trata de un duplicado, lo siento por no encontrar uno.

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

La conversión no es legal. Más precisamente, no hay una conversión implícita de int* a int** , o de int*** a int** . Intentar pasar un int* o un int*** a una función que requiere un argumento int** es una violación de restricción ; cualquier compilador conforme debe diagnosticarlo. (El mensaje de diagnóstico puede ser una advertencia no fatal).

Cuando compilo su código con gcc, incluso con las opciones predeterminadas (lo que hace que gcc no cumpla), recibo varias advertencias:

 cc: In function 'func': cc:4:3: warning: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'int **' [-Wformat=] printf("Pointer is at %x\n", p); ^ cc: In function 'main': cc:9:3: warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default] func(p); ^ cc:3:6: note: expected 'int **' but argument is of type 'int *' void func(int **p) { ^ cc:12:3: warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default] func(&pp); ^ cc:3:6: note: expected 'int **' but argument is of type 'int ***' void func(int **p) { ^

No sé por qué ideone no se queja ( http://ideone.com/uzeXur ).

over 4 years ago · Santiago Trujillo Relatório

0

El compilador aparentemente no tiene advertencias habilitadas:

 int main() { int *p = 0, **p2 = p; ... $ gcc -std=c11 test.c -lncurses test.c: In function 'main': test.c:8:21: warning: initialization from incompatible pointer type [enabled by default] int *p = 0, **p2 = p; ^

Entonces, gcc se queja muy bien. Ese sitio podría haber deshabilitado las advertencias o se lo traga. No debería hacer nada.

Para gcc, también puede convertir todas las advertencias en errores con -Werror o simplemente algunos específicos: -Werror=<name of warning> . Para esto, sería strict-aliasing .

La razón por la que esto no es predeterminado es probablemente por razones históricas. Hacer que sea un error de forma predeterminada podría romper demasiado software heredado o roto en la naturaleza.

La razón por la que no produce un error se puede encontrar aquí en el estándar . Oración 7. Solo es UB si el puntero no está correctamente alineado para el puntero de recepción o no está referenciado (lo que no se hace aquí).

over 4 years ago · Santiago Trujillo Relatório

0

Creo que ideone es suave con las advertencias. Sin -Wall o cualquier indicador de advertencia adicional en mi computadora, gcc me da

 test_ptrs.c: In function 'func': test_ptrs.c:4:3: warning: format '%x' expects argument of type 'unsigned int', but argument 2 has type 'int **' [-Wformat=] printf("Pointer is at %x\n", p); ^ test_ptrs.c: In function 'main': test_ptrs.c:9:3: warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default] func(p); ^ test_ptrs.c:3:6: note: expected 'int **' but argument is of type 'int *' void func(int **p) { ^ test_ptrs.c:12:3: warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default] func(&pp); ^ test_ptrs.c:3:6: note: expected 'int **' but argument is of type 'int ***' void func(int **p) {
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda