Code: Alles auswählen
const char* static blub = "abc"; // OK
const char* blab = blub; // OK
const char* static blob = blab; // error
EDIT: Wobei das im konkreten Fall wohl auch nur ein etwas besserer Ersatz für das ATOM wär...
Code: Alles auswählen
const char* static blub = "abc"; // OK
const char* blab = blub; // OK
const char* static blob = blab; // error
Code: Alles auswählen
void foo()
{
char name[] = "foo";
use(name); // OK
store(name); // error: object lifetime too short
store("foo"); // OK
}
const char *storedName;
void use(const char *name)
{
storedName = name; // error: object lifetime unspecified
}
void store(const char *extern name)
{
storedName = name; // OK
}
Um das zu verhindern, bräuchte man wohl relativ interessantes Verhalten, nämlich dass ein Pointer auf ein Objekt mit local automatic storage nur in einen Pointer der selbst local automatic storage duration hat gespeichert werden kann. Sowas wie cv qualifier, nur dass diese Qualifier mehr oder weniger über eine Ebene an Indirektion hinweg interagieren würden (der top-level local Qualifier ist für lokale Variablen implizit):CodingCat hat geschrieben:Richtig, sowas bräuchte man nicht nur hier. Ich bin auch schon am überlegen, wie man permanente Zeiger und temporäre Zeiger allgemeiner formalisieren könnte. Sehr häufig gibt man Zeiger (Referenzen) auf Stack-Objekte weiter, die mit der Zerstörung des jeweiligen Stack-Objekts ungültig werden. Das ist i.d.R. auch überhaupt kein Problem, weil zuvor alle Unteraufrufe wieder vom Stack verschwinden.
Code: Alles auswählen
local int x; // OK
local int* local px = &x; // OK
int** blub = new int*;
*blub = &px; // error
Ganz genau. Und ganz genau, deshalb liegt dieses Proposal bei dem anderen, das ebenfalls 99.99999% aller vorhandenen C++ Programme zerstören würde; auf Halde.dot hat geschrieben:Um das zu verhindern, bräuchte man wohl relativ interessantes Verhalten, nämlich dass ein Pointer auf ein Objekt mit local automatic storage nur in einen Pointer der selbst local automatic storage duration hat gespeichert werden kann. Sowas wie cv qualifier, nur dass diese Qualifier mehr oder weniger über eine Ebenen hinweg interagieren würden (der top-level local Qualifier ist für lokale Variablen implizit):
[...]
Das Problem ist wohl nur, dass das so ziemlich 99.99999% aller vorhandenen C++ Programme breaken würde...
Code: Alles auswählen
void f()
{
int x;
int* px = &x; // px is implicitly declared int auto* px, deduced to int local* px
int** blub = new int*; // blub is implicitly declared int * auto * blub, deduced to int * dynamic * blub
*blub = px; // error: px is of type int local*, *blub is of type int dynamic*
}
Code: Alles auswählen
void f()
{
static int x;
int* x = new int; // OK, new int returns int dynamic*, can be converted to int*
int* y = &x; // OK, &x is int static*, can be converted to int*
int a;
int* z = &a; // error, can't convert int local* to int*
}
Code: Alles auswählen
struct A
{
int *p;
};
A g; // g global => p hat Typ int *extern
void foo()
{
int i;
A a; // a lokal => p hat Typ int *local
a.p = &i; // OK
foo(a); // OK
g.p = &i; // error
foo(g); // OK
A &r = a; // Referenz lokal
r.p = &i; // OK
foo(r); // OK
extern A b; // b extern => p hat Typ int *extern
b.p = &i; // error
foo(b); // OK
}
void bar(A &a)
{
int j;
a.p = &j; // error: _Parameter_-Referenz auf a NICHT mehr lokal => p hat Typ int *extern?!
int *p = a.p; // error: p hat Typ int *local?!
// a.p hat einen Zwischentyp, nämlich Referenz auf externes int*local, also int *extern local
}
Code: Alles auswählen
int* g;
void f()
{
int x;
int** y = new int*; // OK, int* auto* can be assigned int* dynamic*
int* px = &x; // OK, int auto* can be assigned int local*
*y = &x; // error, int* can't be assigned int local*
*y = px; // error, int* can't be assigned int auto*
px = *y; // OK, int auto* can be assigned int*
g = px; // error, int* can't be assigned int auto*
px = g; // OK, int auto* can be assigned int*
}
// second level auto is implicitly declared on local variables, top level auto/storage class qualifier is ignored just like with function signatures
Code: Alles auswählen
int* g;
int** h = &g; // OK, int* static* can be converted to int**
void f()
{
int x;
int* px = &x; // OK, no conversion necessary
int** y = new int*; // OK, int** can be converted to int* local*
*y = &x; // error, int local* can't be converted to int*
*y = px; // error, int local* can't be converted to int*
px = *y; // OK, int* can be converted to int local*
g = px; // error, int local* can't be converted to int static*
px = g; // OK, int static* can be converted to int local*
*y = g; // OK, no conversion necessary
y = &g; // OK, int* static* can be converted to int* local*
g = *y; // OK, int* can be converted to int static*
}
Code: Alles auswählen
for (auto &&material : controller.Mesh->GetMaterials())
for (auto &&technique : material->GetTechniques())
for (auto &&pass : technique.EffectDriver->GetPasses())
{
}
Jawoll!CodingCat hat geschrieben:Die Productivity Power Tools 2012 sind da!
Bin ich der einzige, der eigentlich nur ein einziges return; in jedem seiner Konstruktoren haben möchte? Da hat man eine wohldefinierte Initialisierungsreihenfolge (in der Reihenfolge aus der Klassendeklaration), vermeidet Kopien und ich kann auch sonst keinen wirklichen Nachteil erkennen.CodingCat hat geschrieben:Ich habe soeben mein erstes C++ Language Proposal gepostet: More Uniform Initialization in Constructors
Verstehe ich nicht. Hast du in deinem Konstruktor nur das return? Wieso überhaupt im Konstruktor ein return? Inwiefern löst das Probleme mit der Initialisierungsreihenfolge oder mit temporären Variablen? Wie kommst du bei komplexer Initialisierung ohne Kopie/Move aus?eXile hat geschrieben:Bin ich der einzige, der eigentlich nur ein einziges return; in jedem seiner Konstruktoren haben möchte? Da hat man eine wohldefinierte Initialisierungsreihenfolge (in der Reihenfolge aus der Klassendeklaration), vermeidet Kopien und ich kann auch sonst keinen wirklichen Nachteil erkennen.
Tard :Djoggel hat geschrieben:Ich hab ein tolles neues Avatar :geek:
Ach was, der kugelt sich wohlig auf dem Boden. Wenn man den Tabellen glauben darf, war er da aber umgerechnet schon 84, nach einem derart langen Leben auf der Straße muss er also nicht mehr jugendlich aussehen. ;) Er ist btw. derselbe wie auf dem alten Avatar, ich dachte ich mache mal ein Upgrade bezüglich Bildmaße, weil mir das Foto gerade aus einem Directory entgegenhüpfte.Chromanoid hat geschrieben:Apropos @CodingCat, die Katze sieht nicht gesund um nicht zu sagen angefahren aus :shock: ;)