sirven sencillos que punteros para operadores los lenguaje ejemplos ejemplo direccion dev declaracion cadenas aritmetica apuntadores c++ arrays pointers backwards-compatibility

sencillos - punteros c++ pdf



Caso utilizable de puntero a matriz con lĂ­mites no especificados en C++(no en C) (2)

Considera seguir el código:

int main() { int (*p)[]; // pointer to array with unspecified bounds int a[] = {1}; int b[] = {1,2}; p = &a; // works in C but not in C++ p = &b; // works in C but not in C++ return 0; }

En C puro, puede asignar un puntero a este tipo de dirección de una matriz de cualquier dimensión. Pero en C ++ no puedes. Encontré un caso cuando el compilador permite asignar valor a dicho puntero:

struct C { static int v[]; }; int main() { int (*p)[] = &C::v; // works in C++ if ''v'' isn''t defined (only declared) return 0; }

Pero no pude encontrar ningún caso útil de este código.

¿Alguien puede dar un ejemplo útil (en C ++) de puntero a matriz con límites no especificados? ¿O solo queda vestigio de C?


Creo que un compilador debería aceptarlo (independientemente de la configuración -O) porque otra unidad de compilación puede proporcionar una definición de estática. (Esta es quizás una desviación pragmática del estándar; no soy un experto en C ++). El fragmento publicado puede compilarse, pero está incompleto y no puede ejecutarse sin una definición del miembro estático.

Archivo ch:

struct C { static int v[]; };

Archivo x.cpp

#include "c.h" #include <iostream> int main(){ int (*p)[] = &C::v; // works in C++ if ''v'' isn''t defined (only declared) std::cout << *((int*)p) << std::endl; return 0; }

Archivo y.cpp

#include "c.h" int C::v[3] = {1,2,3};

Compilado y enlazado usando (no se diga lo que es viejo) g ++ 4.3.3. Imprime 1.

Y: sí, sé que es un elenco en C.


Tal puntero no puede participar en la aritmética del puntero, las cosas potencialmente útiles que aún se pueden hacer son obtener su tipo con decltype o reinterpret_cast a otro tipo de puntero o intptr_t . Esto es porque la sección 3.9p6 dice:

Un tipo de clase (como " class X ") puede estar incompleto en un punto de una unidad de traducción y completarse más adelante; el tipo " class X " es del mismo tipo en ambos puntos. El tipo declarado de un objeto de matriz puede ser una matriz de tipo de clase incompleta y, por lo tanto, incompleto; si el tipo de clase se completa más adelante en la unidad de traducción, el tipo de matriz se completa; el tipo de matriz en esos dos puntos es del mismo tipo. El tipo declarado de un objeto de matriz puede ser una matriz de tamaño desconocido y, por lo tanto, estar incompleto en un punto de una unidad de traducción y completarse más adelante; los tipos de matriz en esos dos puntos ("matriz de límite desconocido de T " y "matriz de N T ") son tipos diferentes. El tipo de un puntero a una matriz de tamaño desconocido, o de un tipo definido por una declaración typedef como una matriz de tamaño desconocido, no se puede completar.

5.3.1 dice:

Nota: la indirección a través de un puntero a un tipo incompleto (que no sea cv void ) es válida. El valor l así obtenido se puede usar de manera limitada (para inicializar una referencia, por ejemplo); este lvalue no se debe convertir a un valor pr, ver 4.1.

Como el decaimiento de matriz a puntero se puede realizar en valores de matriz sin conversión previa a valor de r, el código dyp que queda en un comentario es correcto:

(*p)[i]

Regla relevante, de 4.2:

Un lvalue o rvalue de tipo ''array of N T "o " array of unknown bound of T " se puede convertir a un prvalue de tipo" puntero a T ". El resultado es un puntero al primer elemento de la matriz.