Forum: PC-Programmierung C: Variablen in Bedingungsanweisungen definieren


von zitter_ned_aso (Gast)


Lesenswert?

Hallo,

funktioniert sowas unter C? (unter C++ scheint das OK zu sein)
1
if(int a=1)                                                   
2
    printf("%d \n", a);

Mein Compiler will das nicht haben (nicht dass ich es bräuchte, wollte 
nur mal ausprobieren). Und falls es so nicht geht, dann warum.

Die Fehlermeldung lautet "error: expected expression before ‘int’". Ist 
eine Variablendefinition keine Anweisung?

von Nachdenklicher (Gast)


Lesenswert?

Also mal ehrlich, als Compiler würde ich mich da auch weigern.
Egal ob valide oder nicht, guter Stil geht anders.

Davon abgesehen, wo ist der Sinn darin, einen Konstanten Wert in eine 
Variable zu packen, und drumherum eine Abfrage auf den Wert ebendieser 
Variable zu machen? Ein
1
printf("1\n");
hätte den (gewünschten) Effekt ebenso.

von Walter T. (nicolas)


Lesenswert?

Kein Ausdruck

von Jemand (Gast)


Lesenswert?

Nachdenklicher schrieb:
> [...]

"Nachdenklicher"
Na ja, viel Glück beim nächsten Mal.

von Nachdenklicher (Gast)


Lesenswert?

Wo genau ist Dein Problem? So wie der Code da oben steht, versucht er, 
eine Variable innerhalb der Bedingung mit dem Wert 1 zu initialisieren. 
Das Ergebnis dieser Zuweisung ist 1 - also ist die Bedingung wahr. Warum 
braucht man dann überhaupt noch ein if, wenn die Bedingung konstant true 
ergibt? Naaaa?

von Jemand (Gast)


Lesenswert?

Nachdenklicher schrieb:
> Wo genau ist Dein Problem? So wie der Code da oben steht, versucht
> er,
> eine Variable innerhalb der Bedingung mit dem Wert 1 zu initialisieren.
> Das Ergebnis dieser Zuweisung ist 1 - also ist die Bedingung wahr. Warum
> braucht man dann überhaupt noch ein if, wenn die Bedingung konstant true
> ergibt? Naaaa?

Mit etwas Spurenintelligenz lässt sich erkennen, dass dies ein stark 
vereinfachtes Beispiel ist, wo dieses Feature genutzt wird. Solche 
Beispiele haben üblicherweise die Eigenschaft, nichts Nützliches zu 
erreichen.

von (prx) A. K. (prx)


Lesenswert?

zitter_ned_aso schrieb:
> Und falls es so nicht geht, dann warum.

Sprachdefinition:
   if ( expression ) statement
aber
   int a=1
ist keine "expression"

: Bearbeitet durch User
von CppBert (Gast)


Lesenswert?

@Nachdenklicher

Er Frag einfach nur warum dieses C++17 Feature: 
https://skebanga.github.io/if-with-initializer/

nicht in C geht

von Nick M. (Gast)


Lesenswert?

Nachdenklicher schrieb:
> Also mal ehrlich, als Compiler würde ich mich da auch weigern.

Das ergibt einen pointer.
Pointer uff the Stirn :-)

von SchlechterIng (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> Hallo,
>
> funktioniert sowas unter C? (unter C++ scheint das OK zu sein)
>
1
if(int a=1)
2
>    printf("%d \n", a);
>
> Mein Compiler will das nicht haben (nicht dass ich es bräuchte, wollte
> nur mal ausprobieren). Und falls es so nicht geht, dann warum.
>
> Die Fehlermeldung lautet "error: expected expression before ‘int’". Ist
> eine Variablendefinition keine Anweisung?

Was die Kollegen hier sagen wollen:
1
if(int a==1)
2
     printf("%d \n", a);

int=1 setzt Du a gleich 1 und somit wahr. Der Kompiler merkt das und 
wird wahrscheinlich eine Fehlermeldung ausspucken... Beim nächsten mal 
die Fehlermeldung des Kompilers mit hier angeben bzw. darauf achten.

von zitter_ned_aso (Gast)


Lesenswert?

Nachdenklicher schrieb:
> printf("1\n");hätte den (gewünschten) Effekt ebenso.

ja, aber ich könnte dieser Variable auch was anderes zuweisen.

Oder z.B. das hier:
1
 while(int ch=getchar()){                                              
2
      if(ch=='e'){                                                      
3
          puts("end");                                                  
4
            break;                                                      
5
      }                                                                 
6
      putchar(ch);                                                      
7
 }

eine lokale Variable ch (wie bei einer for-Schleife). Läuft wieder mit 
dem C++-Compiler.

von vn nn (Gast)


Lesenswert?

Abstraktes Denken ist nicht so deine Stärke?
Genau so gut könnte natürlich dastehen
1
if(int a=foo())
2
     printf("%d \n", a);
3
}

zitter_ned_aso schrieb:
> Mein Compiler will das nicht haben (nicht dass ich es bräuchte, wollte
> nur mal ausprobieren). Und falls es so nicht geht, dann warum.
>
> Die Fehlermeldung lautet "error: expected expression before ‘int’". Ist
> eine Variablendefinition keine Anweisung?

In C99 ist nur folgendes legal:
1
#include <stdio.h>
2
#include <stdlib.h>
3
4
int main (void)
5
{
6
    int a;
7
    if (a = rand()) {
8
        printf("%d", a);
9
    }
10
}

Warum? Weils so im Standard steht, Variablendeklation in einer 
Expression ist nicht zulässig.

von zitter_ned_aso (Gast)


Lesenswert?

SchlechterIng schrieb:
> int=1 setzt Du a gleich 1 und somit wahr. Der Kompiler merkt das und
> wird wahrscheinlich eine Fehlermeldung ausspucken...

ach so! bei werden werden Warnungen als Errors behandelt - vielleicht 
liegt es daran. Danke für diesen Hinweis. Ich habe es ganz vergessen.

von zitter_ned_aso (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> bei werden

Bei mir

von x^2 (Gast)


Lesenswert?

In C++ mit GCC scheint das zu gehen (ich sehe allerdings keine sinnvolle 
Anwendung dafür):
1
if (int i = 42)
2
{
3
   printf("true: %d", i);
4
}
5
  else
6
  {
7
     printf("false: %d", i);
8
  }

In C99 scheint es hingegen nicht möglich zu sein.

Wenn ich mich recht entsinne, gab es zwischen C99 und C++ ein paar 
subtile Unterschiede in dieser Hinsicht bei Schleifen: Bei C99 existiert 
eine solche Variable afaik in einem separaten Scope, während sie bei C++ 
als Bestandteil des gleichen Scopes der for Schleife ist.

In C99 sollte folgendes daher kompilieren, in C++ hingegen nicht:
1
for (int i = 0; i < 10; ++i)
2
{
3
   int i = 42;
4
   printf("%d", i);
5
}

von zitter_ned_aso (Gast)


Lesenswert?

Walter T. schrieb:
> Kein Ausdruck

Ja, einverstanden.

Sonst könnte man das ja so weiter treiben:
1
printf("%d\n", int x=42);

von Jemand (Gast)


Lesenswert?

x^2 schrieb:
> (ich sehe allerdings keine sinnvolle
> Anwendung dafür):

Die Anwendung dafür ist, dass man den Rückgabewert einer Funktion 
überprüfen und gegebenfalls weiterverwenden kann, ohne das man das 
außenliegende Scope vollmüllen muss (und wohlmöglich ungültige Daten 
weitergenutzt werden) oder lästig noch mehr Klammern setzen muss.

von Arno (Gast)


Lesenswert?

Könnte auch von der Version des C-Standards abhängen, die du verwendest.

Für for-Schleifen weiß ich, dass die Deklaration innerhalb des 
Schleifenkopfs erst seit C99 zulässig ist: 
https://stackoverflow.com/questions/1287863/c-for-loop-int-initial-declaration

MfG, Arno

von x^2 (Gast)


Lesenswert?

CppBert schrieb:
> @Nachdenklicher
>
> Er Frag einfach nur warum dieses C++17 Feature:
> https://skebanga.github.io/if-with-initializer/
>
> nicht in C geht

Langsam verlieren sich diese C++ Leute auch im klein-klein und syntactic 
sugar.

von zitter_ned_aso (Gast)


Lesenswert?

Die Frage war halt ob die Variablendefinition eine Anweisung ist, die 
einen Rückgabewert zurückgibt (den man dann z.B. mit "if" auswerten 
kann).


Und wenn C++ sowas  wie
1
if( int i=get_value() )
akzeptiert, warum wird dann bei
1
cout<< int x=42 <<endl;
gemeckert?

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> Langsam verlieren sich diese C++ Leute auch im klein-klein und syntactic
> sugar.

Mitnichten: es geht hier um die Begrenzung des Scope. Und das ist sehr 
wichtig und nützlich.

von mh (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> Und wenn C++ sowas  wieif( int i=get_value() )
> akzeptiert, warum wird dann beicout<< int x=42 <<endl;
> gemeckert?

Weil das eine nichts mit dem anderen zu tun hat?

von DPA (Gast)


Lesenswert?

zitter_ned_aso schrieb:
> while(int ch=getchar()){

Ist das nicht eine endlosschleife? EOF ist normalerweise nicht 0.

von Wilhelm M. (wimalopaan)


Lesenswert?

zitter_ned_aso schrieb:
> Die Frage war halt ob die Variablendefinition eine Anweisung ist, die
> einen Rückgabewert zurückgibt (den man dann z.B. mit "if" auswerten
> kann).
>
>
> Und wenn C++ sowas  wie
>
1
> if( int i=get_value() )
2
>
> akzeptiert, warum wird dann bei
>
1
> cout<< int x=42 <<endl;
2
>
> gemeckert?

Schon mal was von Syntax gehört?
Das eine ist eine an der Stelle expl. zugelassene Definition, das andere 
muss eine Ausdruck sein.

von x^2 (Gast)


Lesenswert?

Wilhelm M. schrieb:
> x^2 schrieb:
>> Langsam verlieren sich diese C++ Leute auch im klein-klein und syntactic
>> sugar.
>
> Mitnichten: es geht hier um die Begrenzung des Scope. Und das ist sehr
> wichtig und nützlich.

Ich mag nicht streiten, aber das geht doch bereits mit einem klassischem 
Scopeblock:
1
{
2
   auto x = f();
3
   if (x == 42) { ... }
4
}

In meinen Augen ist das deshalb nur syntactic sugar. Man müßte ja drei 
Zeichen mehr tippen und spart sich die Einrückung (Oh nein, der Herr 
behüte!).

Pattern durch Scopeblöcke sind ja durchaus üblich a la:
1
{
2
   Mutex lock(x);
3
   // do things in critical section here, may throw exceptions
4
}
5
// auto release mutex here

Zumal dieses neue Feature ja nur mit einer Variable geht. Folgendes geht 
ja aus gutem Grund nicht, da gar nicht klar wäre, welche Variable danach 
überhaupt existiert:
1
if (auto a = f1() || auto b = f2() || auto c = f3())
2
{
3
   // does b and c exist here?
4
}

Spätestens dann ist man wieder beim Scopeblock.

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Schon mal was von Syntax gehört?
> Das eine ist eine an der Stelle expl. zugelassene Definition, das andere
> muss eine Ausdruck sein.

Ich finde es schon bemerkenswert. Eigentlich hat "int i = get_value()" 
keinen Wert, da es kein Ausdruck ist. Dennoch kann man im if den Wert 
offenbar abfragen. Es scheint sich also um eine kontextabhängige 
Erweiterung der Syntax zu handeln, die man im Sprachdesign normalerweise 
zu vermeiden versucht.

von mh (Gast)


Lesenswert?

Rolf M. schrieb:
> Es scheint sich also um eine kontextabhängige Erweiterung der Syntax zu
> handeln, die man im Sprachdesign normalerweise zu vermeiden versucht.

Der Zug ist bei C und damit C++ schon lange abgefahren ;-)

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> Ich mag nicht streiten, aber das geht doch bereits mit einem klassischem
> Scopeblock:
> {
>    auto x = f();
>    if (x == 42) { ... }
> }

Du musst es ja nicht nutzen.

Trotzdem halte ich
1
if (const auto x = f(); isBla(x)) {
2
   // ...
3
}

für sinnvoll, weil es einfach Fehler vermeiden hilft.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Es scheint sich also um eine kontextabhängige Erweiterung der Syntax zu
> handeln, die man im Sprachdesign normalerweise zu vermeiden versucht.

Naja, so wie bei "for" auch, wo es C99 ja übernommen hat (wenngleich, 
wie etwas weiter oben gezeigt, leider mit geringfügig anderen 
Randbedingungen bzgl. des Scopes).

Ja, ist manchmal praktisch, als Kurzform dafür, einen komplett neuen 
Klammer-Block anlegen zu müssen. Hätte man wohl für "if" auch übernehmen 
können, andererseits, wie ebenfalls genannt worden ist, mehr als eine 
Variable lässt sich damit eben nicht definieren – weder bei "for" noch 
bei "if" weder in C noch in C++. Da hat die Bequemlichkeit dann ihre 
Grenzen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Da hat die Bequemlichkeit dann ihre
> Grenzen.

Bequemlichkeit ist ja auch nicht das Ziel.

von x^2 (Gast)


Lesenswert?

Okay, folgendes ginge dafür:
1
if (auto a = 42, b = 43, c = 44; a || b || c)
2
{
3
   printf("%d, %d, %d", a, b, c);
4
}

spart allerdings auch nur 2 Zeichen Tipparbeit
1
{
2
   auto a = 42, b = 43, c = 44;
3
   if (a || b || c)
4
   {
5
      printf("%d, %d, %d", a, b, c);
6
   }
7
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Bequemlichkeit ist ja auch nicht das Ziel.

Doch. Es wurde doch schon gezeigt, dass ein neuer Klammerblock eine 
vergleichbare Begrenzung des Scopes produzieren würde. Letztlich genau 
das, was man tun muss, um es für mehr als eine Variable haben zu können.

von Wilhelm M. (wimalopaan)


Lesenswert?

Jörg W. schrieb:
> Doch.

Nein.

>Es wurde doch schon gezeigt, dass ein neuer Klammerblock eine
> vergleichbare Begrenzung des Scopes produzieren würde.

Die Aussage des Codes ist eine andere, und die Fehlermöglichkeiten auch.

von Rolf M. (rmagnus)


Lesenswert?

Jörg W. schrieb:
> Rolf M. schrieb:
>> Es scheint sich also um eine kontextabhängige Erweiterung der Syntax zu
>> handeln, die man im Sprachdesign normalerweise zu vermeiden versucht.
>
> Naja, so wie bei "for" auch, wo es C99 ja übernommen hat (wenngleich,
> wie etwas weiter oben gezeigt, leider mit geringfügig anderen
> Randbedingungen bzgl. des Scopes).

diese Variante ist analog zur for-Schleife:

Wilhelm M. schrieb:
> if (const auto x = f(); isBla(x)) {

Da wurden die Definition der Variablen und die Abfrage der Bedingung 
sauber getrennt. Hier aber nicht:

zitter_ned_aso schrieb:
> if( int i=get_value() )

von mh (Gast)


Lesenswert?

Jörg W. schrieb:
> Ja, ist manchmal praktisch, als Kurzform dafür, einen komplett neuen
> Klammer-Block anlegen zu müssen. Hätte man wohl für "if" auch übernehmen
> können, andererseits, wie ebenfalls genannt worden ist, mehr als eine
> Variable lässt sich damit eben nicht definieren – weder bei "for" noch
> bei "if" weder in C noch in C++. Da hat die Bequemlichkeit dann ihre
> Grenzen.

Es lassen sich schon mehrere Variablen anlegen:
1
std::set<double> m;
2
if(auto [it, flag] = m.insert(6.6); flag) {
3
  foo(*it);
4
}
Ok es lässt sich nicht direkt das Beispiel von x^2 umsetzen, aber das 
scheint eh eine schlechte Idee zu sein. Wenn die Funktionen echte Namen 
haben und länger als 2 Zeichen sind wird das sehr schnell sehr 
unübersichtlich.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Da wurden die Definition der Variablen und die Abfrage der Bedingung
> sauber getrennt. Hier aber nicht:

Stimmt.

von Jemand (Gast)


Lesenswert?

x^2 schrieb:
> Zumal dieses neue Feature ja nur mit einer Variable geht.

Das Feature gibt es seit C++98.

von GEKU (Gast)


Lesenswert?

Variablen in Bedingungsanweisungen zu definieren ist in C nicht 
vorgesehen und funktioniert erst in C++.

Also cpp anstelle von gcc verwndet.

von Philipp Klaus K. (pkk)


Lesenswert?

GEKU schrieb:
> Variablen in Bedingungsanweisungen zu definieren ist in C nicht
> vorgesehen und funktioniert erst in C++.
>
> Also cpp anstelle von gcc verwndet.

Du meinst wohl g++.

von Rolf M. (rmagnus)


Lesenswert?

Philipp Klaus K. schrieb:
>> Also cpp anstelle von gcc verwndet.
>
> Du meinst wohl g++.

Vermutlich, denn cpp ist der C-Präprozessor.

von x^2 (Gast)


Lesenswert?

Jemand schrieb:
> Das Feature gibt es seit C++98.

Das wird für C++17 als neu feil geboten. Sicher dass wir vom gleichen 
reden? Ich meinte sowas:
1
if (auto x = f())
2
{
3
   printf("%d", x);
4
}

von x^2 (Gast)


Lesenswert?

Warte hast recht. Neu scheint nur die Form
1
if (auto x = f(); x)
2
{
3
    printf("%d", x);
4
}

von Yalu X. (yalu) (Moderator)


Lesenswert?

Um die Verwirrung zu vervollständigen:

1
#include <iostream>
2
3
int f1() { return 1; }
4
5
int f2() { return 2; }
6
7
int f3() { return 3; }
8
9
int main () {
10
11
  if (int y1=f1(); int y2=f2())             // korrekt
12
    std::cout << y1 + y2 << '\n';
13
14
  if (int y1=f1(); int y2=f2(); y3=f3())    // syntaktisch falsch
15
    std::cout << y1 + y2 + y3 << '\n';
16
}

Ja, ich weiß, warum die zweite if-Anweisung so nicht möglich ist, aber
auf den ersten Blick sieht das Beispiel doch etwas paradox aus.

Ich empfinde ja viele der neu hinzugekommenen Sprachfeatures seit C++11
durchaus als sinnvoll und nützlich. Wenn aber für irgendwelche relativ
unwichtigen Dinge (bspw.um zwei Zeichen einzusparen) die Sprachsyntax
geändert wird, keimt in mir der leise Verdacht auf, dass es dem
Normungsgremium nicht immer nur um die Verbesserung der Sprache geht,
sondern manchmal auch um den Ausschluss jener Programmierer aus der
C++Community, die nicht die Möglichkeit haben, ihr C++-Wissen alle drei
Jahre auf den neuesten Stand zu bringen ;-)

: Bearbeitet durch Moderator
von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Ich empfinde ja viele der neu hinzugekommenen Sprachfeatures seit C++11
> durchaus als sinnvoll und nützlich. Wenn aber für irgendwelche relativ
> unwichtigen Dinge (bspw.um zwei Zeichen einzusparen)

Wie schon gesagt: darum geht es nicht.

> die Sprachsyntax
> geändert wird, keimt in mir der leise Verdacht auf, dass es dem
> Normungsgremium nicht immer nur um die Verbesserung der Sprache geht,
> sondern manchmal auch um den Ausschluss jener Programmierer aus der
> C++Community, die nicht die Möglichkeit haben, ihr C++-Wissen alle drei
> Jahre auf den neuesten Stand zu bringen ;-)

Blödsinn.
Hier haben wir die seit langem auf dem Plan stehende Vereinfachung, weil 
for/if/switch nun gleich behandelt werden. Das macht die Sprache 
einfacher.

Und beim for-statement würdest Du es je wohl auch nicht gegenüber der 
c89-Version als Verschlechterung empfinden.

Das ist dieselbe Qualität wie uniform-initialization-Syntax (wichtig für 
generische Programierung).

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Es lassen sich schon mehrere Variablen anlegen:std::set<double> m;
> if(auto [it, flag] = m.insert(6.6); flag) {
>   foo(*it);
> }
> Ok es lässt sich nicht direkt das Beispiel von x^2 umsetzen, aber das
> scheint eh eine schlechte Idee zu sein.

Nein, eigentlich hast Du das Schulbeispiel benannt.

Wobei es streng genommen nicht zwei Variablen sind, sondern nur eine 
(die einen unbekannten, eindeutigen Namen hat) als Aggregat, mit neuen 
Namen für die Elemente des Aggregats.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Yalu X. schrieb:
>> Ich empfinde ja viele der neu hinzugekommenen Sprachfeatures seit C++11
>> durchaus als sinnvoll und nützlich. Wenn aber für irgendwelche relativ
>> unwichtigen Dinge (bspw.um zwei Zeichen einzusparen)
>
> Wie schon gesagt: darum geht es nicht.

Dann erklär doch mal einem nicht so Fortgeschrittenen, warum

1
  if ( init-statement condition ) statement

so viel besser sein soll als

1
  {
2
    init-statement
3
    if ( condition ) statement
4
  }

dass man dafür extra die (ohnehin schon recht komplizierte) Syntax
erweitern muss.

Wilhelm M. schrieb:
> Hier haben wir die seit langem auf dem Plan stehende Vereinfachung, weil
> for/if/switch nun gleich behandelt werden. Das macht die Sprache
> einfacher.

Das Argument würde ich ja sofort gelten lassen, wenn dabei
konsequenterweise auch while berücksichtigt worden wäre, also:

1
  while ( init-statement condition ) statement

Stattdessen geht nach wie vor nur

1
  while ( condition ) statement

Wo bleibt da die Durchgängigkeit?

von x^2 (Gast)


Lesenswert?

Yalu X. schrieb:
> Ja, ich weiß, warum die zweite if-Anweisung so nicht möglich ist, aber
> auf den ersten Blick sieht das Beispiel doch etwas paradox aus.

paradox++
:-)
1
class Test
2
{
3
    public:
4
        Test() = delete;
5
        Test(int x) : m_value(x) { printf("%p: create\n", this); }
6
        ~Test() { printf("%p: destroy\n", this); }
7
        operator int() const { return m_value; }
8
    private:
9
        int m_value;
10
};
11
12
int main()
13
{
14
    if (Test x(1); Test y = 2)
15
    {
16
        printf("x=%d, y=%d\n", (int)x, (int)y);
17
    }
18
    return 0;
19
}

Das compiliert und läut:
1
0x7ffcab9e8d68: create
2
0x7ffcab9e8d6c: create
3
x=1, y=2
4
0x7ffcab9e8d6c: destroy
5
0x7ffcab9e8d68: destroy

Markiert man den parametrierten Konstruktor oder den Konversionsoperator 
nach int als explicit, compiliert es nicht mehr - soweit so klar. Jetzt 
aber folgende Änderung:
1
if (Test x(1); Test y(2))
2
{
3
    printf("x=%d, y=%d\n", (int)x, (int)y);
4
}

DAS kompiliert NICHT mehr!
1
main.cpp: In function ‘int main()’:
2
main.cpp:24:25: error: expected primary-expression before ‘y’
3
     if (Test x(1); Test y(2))
4
                         ^

WTF?!

von Vincent H. (vinci)


Lesenswert?

Clang hat hier eine wesentlich bessere Fehlermeldung:
1
<source>:15:23: error: variable declaration in condition cannot have a parenthesized initializer
2
3
  if (Test x(1); Test y(2)) {

von x^2 (Gast)


Lesenswert?

Vincent H. schrieb:
> Clang hat hier eine wesentlich bessere Fehlermeldung:
> <source>:15:23: error: variable declaration in condition cannot have a
> parenthesized initializer
>
>   if (Test x(1); Test y(2)) {

Okay, aber warum geht das:
1
if (Test x{1}; Test y{2})
2
{
3
    printf("x=%d, y=%d\n", (int)x, (int)y);
4
}

von mh (Gast)


Lesenswert?

Yalu X. schrieb:
> Wilhelm M. schrieb:
>> Yalu X. schrieb:
>>> Ich empfinde ja viele der neu hinzugekommenen Sprachfeatures seit C++11
>>> durchaus als sinnvoll und nützlich. Wenn aber für irgendwelche relativ
>>> unwichtigen Dinge (bspw.um zwei Zeichen einzusparen)
>>
>> Wie schon gesagt: darum geht es nicht.
>
> Dann erklär doch mal einem nicht so Fortgeschrittenen, warum
>
>   if ( init-statement condition ) statement
>
> so viel besser sein soll als
>
>   {
>     init-statement
>     if ( condition ) statement
>   }
>
> dass man dafür extra die (ohnehin schon recht komplizierte) Syntax
> erweitern muss.

Also ich finde
1
if ( init-statement1 condition1 ) {
2
  if ( init-statement3 condition2 ) {
3
    if ( init-statement3 condition3 ) {
4
      foo();
5
    }
6
  }
7
}

deutlich besser als
1
{
2
  init-statement1
3
  if ( condition1 ) {
4
    init-statement2
5
    if ( condition2 ) {
6
      init-statement3
7
      if ( condition3 ) {
8
        foo();
9
      }
10
    }
11
  }
12
}

Der Vergleich wird noch vorteilhafter, wenn sowas wie "else" und weitere 
Funktionsaufrufe vorkommen.

Yalu X. schrieb:
> Wilhelm M. schrieb:
>> Hier haben wir die seit langem auf dem Plan stehende Vereinfachung, weil
>> for/if/switch nun gleich behandelt werden. Das macht die Sprache
>> einfacher.
>
> Das Argument würde ich ja sofort gelten lassen, wenn dabei
> konsequenterweise auch while berücksichtigt worden wäre, also:
>
>   while ( init-statement condition ) statement
>
> Stattdessen geht nach wie vor nur
>
>   while ( condition ) statement
>
> Wo bleibt da die Durchgängigkeit?

Das habe ich bis jetzt auch nicht verstanden. Hat das bis jetzt niemand 
Vorgeschlagen oder wurde es abgelehnt?

von x^2 (Gast)


Lesenswert?

Yalu X. schrieb:
> Stattdessen geht nach wie vor nur
>
>   while ( condition ) statement
>
> Wo bleibt da die Durchgängigkeit?

vielleicht hat man sich ja um folgendes Problem gedrückt:
1
auto x = 42;
2
do
3
{
4
   // x usage from different scopes here?
5
} 
6
while (auto x = f(); x);

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Das habe ich bis jetzt auch nicht verstanden. Hat das bis jetzt niemand
> Vorgeschlagen oder wurde es abgelehnt?

Ich schätze, weil es "for" gibt, wenn man eine Schleife mit init haben 
will.

von Rolf M. (rmagnus)


Lesenswert?

x^2 schrieb:
> Vincent H. schrieb:
>> Clang hat hier eine wesentlich bessere Fehlermeldung:
>> <source>:15:23: error: variable declaration in condition cannot have a
>> parenthesized initializer
>>
>>   if (Test x(1); Test y(2)) {
>
> Okay, aber warum geht das:if (Test x{1}; Test y{2})
> {
>     printf("x=%d, y=%d\n", (int)x, (int)y);
> }

Weil das kein parenthesized initializer, sondern ein brace-initializer 
ist.

von x^2 (Gast)


Lesenswert?

mh schrieb:
> Der Vergleich wird noch vorteilhafter, wenn sowas wie "else" und weitere
> Funktionsaufrufe vorkommen.

Würde ich jetzt nicht bestreiten wollen; aber es bringt die Sprache 
nicht weiter und bietet (Hand auf Herz) nur marginalen Mehrwert. Es ist 
kein neues fundamentales Konzept, so wie einst Klassen, Namespaces oder 
Templates.

Ich neige dazu solchen syntactic sugar etwas kritisch zu sehen: Die 
Leute nutzen das dann begeistert und zwingen dadurch jeden der eine 
kleine Klasse von ihnen wiederverwenden möchte dazu, erstmal auf die 
allerneuste Compiler-Version upzudaten, weil jetzt die if's anders sind. 
Für kleine Spielprojekte ist das immer schnell erledigt, aber bei den 
großen Projekte in der Industrie, die nicht nur Programmiergold 
enthalten ist so ein Compiler-Update durchaus mal kritisch und nicht so 
eben mal getan.

Im Fall der while Loop wurde ja oben (m.M. nach absolut berechtigt) 
angeführt, dass dieses spezielle Feature die Durchgängigkeit und Logik 
kaputt macht. Das hätte man vermeiden können, indem man einfach etwas 
länger über solche Dinge nachdenkt und "mental reifen" läßt. Das ist im 
Wesentlichen auch meine Kritik an der C++ Weiterentwicklung der letzten 
Zeit: Vieles ist zu hastig vorwärtsgetrieben und man läuft schnell 
Gefahr mehr kaputt zu machen wie besser.

von x^2 (Gast)


Lesenswert?

Rolf M. schrieb:
> Weil das kein parenthesized initializer, sondern ein brace-initializer
> ist.

Das wäre eine formale Erklärung; Auf logischer Ebene macht es afaik aber 
keinen Unterschied: Die Konstruktion der Objekte läuft identisch ab. Es 
ist unlogisch warum das eine gehen sollte, das andere aber nicht.

von mh (Gast)


Lesenswert?

x^2 schrieb:
> Das hätte man vermeiden können, indem man einfach etwas
> länger über solche Dinge nachdenkt und "mental reifen" läßt.

Weil jede dumme Idee sofort im nächsten Standard landet... Warum gehen 
so viele Leute davon aus, dass am Standard nur böswillige und/oder 
unfähige Idioten arbeiten?

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> x^2 schrieb:
>> Das hätte man vermeiden können, indem man einfach etwas
>> länger über solche Dinge nachdenkt und "mental reifen" läßt.
>
> Weil jede dumme Idee sofort im nächsten Standard landet... Warum gehen
> so viele Leute davon aus, dass am Standard nur böswillige und/oder
> unfähige Idioten arbeiten?

Weil...

Es es einfch nur peinlich ist, wenn irgendwelche APIs verabschiedet 
werden, die dann direkt im nächsten Standard deprecated werden, weil sie 
einfach beschi**en war. Mal im ernst, was soll man da denken? Da sitzt 
dann das Komitee und erwägt Jahre lang hin und her und dann kommt etwas 
raus, was nach dem ersten "Testlauf" (lies: beschlossener 
internationaler Standard) sofort auseinander fliegt?

Oder man denke mal an c++11 constexpr. "Exactly one return statement" 
WTF!?
Warum??? Das wird so gesetzt, weil... Ja, das muss schon ein toller 
Grund gewesen sein, wenn er ein paar Jahre später nicht mehr gilt. Was 
hat sich verändert? Wurde bewiesen, dass mit einem erweiterten 
Epsilon-Lambda-Kalkül komplexere Ausdrücke doch widerspruchsfrei 
möglich sind? Habe ich was verpasst? Ist keiner auf die Idee gekommen, 
da mit mehr als einem return arbeiten zu wollen? Oder war das ganze 
halbgar, als es verabschiedet wurde und füllt jetzt "nur so" die cppref 
(und so manchen Programmierer-Schädel) mit irgendwelchen Bestimmungen 
aus grauer Vorzeit, führt zu (hoffentlich) totem Code in so mancher 
Compiler-Implementierung, und erinnert, wie als Mahnmal daran, wie 
armselig die Dinge früher waren?

Herb Sutter erzählte auch ganz ehrlich auf irgendeiner x-com: "Ja, bei 
den braced initialiazers - da dachte ich im nachhinein echt, wir 
hätten's so richtig verbockt, wenn man diese Beispiele hier 
betrachtet..."
Sollte man das fixen? Könnte man das noch, wenn es einmal verabschiedet 
war? So etwas wirkt schon ein wenig diskreditierend - ganz von selbst.

Und mir zumindest scheint das dem Prozess inhärent.
Das Grundprinzip ist scheinbar eben nicht: "Das hat sich bewährt, das 
können wir standartisieren."

von Yalu X. (yalu) (Moderator)


Lesenswert?

Heiko L. schrieb:
> Oder man denke mal an c++11 constexpr. "Exactly one return statement"
> WTF!?
> Warum???

Das hatte vermutlich eher praktische Gründe: Wären constexpr-Funktionen
in C++11 gleich so allgemein spezifiziert worden wie in C++14, wären
wohl die Compilerschreiber auf die Barrikaden gegangen, weil sie in
kurzer Zeit einen C++-Interpreter in den C++Compiler hätten integrieren
müssen, was schon ein Bisschen Arbeit bedeutet. Beschränkt man die
Funktion auf ein einzelnes return-Statement, muss statt eines Stücks
allgemeinen Programmcodes (mit Variablen, Zuweisungen, Schleifen usw.)
nur ein Ausdruck ausgewertet werden, wofür die benötigten Mittel in
bestehenden Compilern bereits verfügbar waren.

Das war immerhin schon ein bedeutender Fortschritt gegenüber C++98/03,
wo algorithmische Compilezeitberechnungen nur mit einem gruseligen
Template-Hack möglich waren. Für diejenigen, die ein wenig funktionale
Programmierung konnten, stellte die Einschränkung auf 1 return-Statement
kein Problem dar, da in FP-Sprachen jede Funktion dieser Einschränkung
unterliegt.

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> mh schrieb:
>> x^2 schrieb:
>>> Das hätte man vermeiden können, indem man einfach etwas
>>> länger über solche Dinge nachdenkt und "mental reifen" läßt.
>>
>> Weil jede dumme Idee sofort im nächsten Standard landet... Warum gehen
>> so viele Leute davon aus, dass am Standard nur böswillige und/oder
>> unfähige Idioten arbeiten?
>
> Weil...
> [...]

Oh nein! Sie machen beim Lösen komplexer Probleme Fehler! Es müssen 
Idioten am Werk sein! Und böswillig dazu!

von Heiko L. (zer0)


Lesenswert?

Yalu X. schrieb:
> Wären constexpr-Funktionen
> in C++11 gleich so allgemein spezifiziert worden wie in C++14, wären
> wohl die Compilerschreiber auf die Barrikaden gegangen, weil sie in
> kurzer Zeit einen C++-Interpreter in den C++Compiler hätten integrieren
> müssen, was schon ein Bisschen Arbeit bedeutet.

Ja, das ist es genau, was ich meine. Das sind Erwägungen, die mMn keinen 
Ausdruck in so etwas wie einem ISO-Standard finden dürf(t)en.
Wenn es darum geht, eine Sprache sinnvoll zu spezifizieren, was soll 
denn das dann für ein Argument sein? Warum sollte jede Implementierung, 
die nicht auf Konformität pfeift, "erstmal" so etwas bereit stellen? Und 
wie schlimm ist es dagegen de-facto eine Zeit lang (noch) nicht 
standardkonform zu sein, wenn dann endlich eine finale (und hoffentlich 
ausgereifte) Fasssung verabschiedet wird? Ich finde, der gesetzte 
Standard sollte gerade kein Testbett und von Kompromissen an 
Compiler-Autoren geprägtes Konstrukt sein, sondern die wohlüberlegte, 
sinnvolle, gereifte Einsicht, wie es sein sollte, die als solche ihre 
Gültigkeit auch nicht eben einbüßen kann.

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Heiko L. schrieb:
>> mh schrieb:
>>> x^2 schrieb:
>>>> Das hätte man vermeiden können, indem man einfach etwas
>>>> länger über solche Dinge nachdenkt und "mental reifen" läßt.
>>>
>>> Weil jede dumme Idee sofort im nächsten Standard landet... Warum gehen
>>> so viele Leute davon aus, dass am Standard nur böswillige und/oder
>>> unfähige Idioten arbeiten?
>>
>> Weil...
>> [...]
>
> Oh nein! Sie machen beim Lösen komplexer Probleme Fehler! Es müssen
> Idioten am Werk sein! Und böswillig dazu!

Wenn das denn so ist, könnte man es schon als Hybris auffassen.

von MaWin (Gast)


Lesenswert?

Heiko L. schrieb:
> Und
> wie schlimm ist es dagegen de-facto eine Zeit lang (noch) nicht
> standardkonform zu sein, wenn dann endlich eine finale (und hoffentlich
> ausgereifte) Fasssung verabschiedet wird?

Und wo ist denn das Problem den Standard erst etwas strikter zu 
definieren und ihn dann aufzuweiten?
Volle Rückwärtskompatibilität ist gegeben.
Es wurde nichts deprecated. Lediglich erweitert.

Hättest du es besser gefunden, wenn man den Standard erst komplex 
definiert und dann einen folgenschweren Fehler macht, weil man doch 
etwas übersehen hat?
Lieber Schritt für Schritt vorgehen.

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> Ja, das ist es genau, was ich meine. Das sind Erwägungen, die mMn keinen
> Ausdruck in so etwas wie einem ISO-Standard finden dürf(t)en.
> Wenn es darum geht, eine Sprache sinnvoll zu spezifizieren, was soll
> denn das dann für ein Argument sein? Warum sollte jede Implementierung,
> die nicht auf Konformität pfeift, "erstmal" so etwas bereit stellen? Und
> wie schlimm ist es dagegen de-facto eine Zeit lang (noch) nicht
> standardkonform zu sein, wenn dann endlich eine finale (und hoffentlich
> ausgereifte) Fasssung verabschiedet wird? Ich finde, der gesetzte
> Standard sollte gerade kein Testbett und von Kompromissen an
> Compiler-Autoren geprägtes Konstrukt sein, sondern die wohlüberlegte,
> sinnvolle, gereifte Einsicht, wie es sein sollte, die als solche ihre
> Gültigkeit auch nicht eben einbüßen kann.

Also einerseits darf der Standard keine kleinen Schritte machen und 
andererseits darf der Standard nur ausgereifte Dinge übernehmen. Wie 
soll das funktionieren? Soll jeder Compiler und jede 
"Standardbibliothek" erstmal drauflos testen?

von Wilhelm M. (wimalopaan)


Lesenswert?

Dann lenken wir doch mal die Diskussion weg von den Selektionen mit 
Initialisieren (if/switch) zu den Iterationen (for/while/do-while), die 
in ihrer Mächtigkeit alle äquivalent sind und deshalb mechanisch 
ineinander transformiert werden können. Es braucht also nur eine Form: 
sagen wird die kopfgesteuerte while-Form.

Die Leute, die hier so gegen die vermeintliche Verkomplizierung der 
Sprache (in der Tat ist es eine Vereinfachung) wettern, und schlechtere 
Pseudoalternativen vorschlagen (nicht im Sinne von Mächtigkeit, auch 
dort kämen wir mit der simplen Form if (<bool>) aus), sollten dann mal 
sich fragen, warum gibt es denn auch noch die for- oder do-while-Form. 
Wahrscheinlich auch, weil das Standardisierungskomitee von Idioten 
durchsetzt ist, die die Sprache C kaputt machen wollen. Jaja, die 
Depperten da oben!

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Dann lenken wir doch mal die Diskussion weg von den Selektionen mit
> Initialisieren (if/switch) zu den Iterationen (for/while/do-while), die
> in ihrer Mächtigkeit alle äquivalent sind und deshalb mechanisch
> ineinander transformiert werden können. Es braucht also nur eine Form:
> sagen wird die kopfgesteuerte while-Form.

Dann können wir noch einen Schritt weiter gehen und alle Schleifen 
streichen. Wir können einfach if + goto nutzen. Das sollte den Standard 
deutlich vereinfachen. Die ganzen Schleifen machen immerhin ganze 3 
Seiten aus.


(für alle die es nicht auswendig wissen, das c++17 Draft Dokument hat 
1440 Seiten)

von x^2 (Gast)


Lesenswert?

Schon komisch, dass mir C++ jüngst durch immer aggressiveres Marketing 
auffällt. Hier auch wieder. Ich denke: Wer austeilt ("We stopped 
teaching C" *) muss auch einstecken können.

Ein gutes Produkt hat sowas jedenfalls nicht nötig und würde Kritik 
ernst nehmen, um so die Sprache zu verbessern.

Den Stohmann, dass im Standardisierungsgremium nur Idioten am Werk sind 
könnt ihr gleich wieder einpacken, den hat "hm" hier mal auf der Wiese 
aufgestellt um sich jetzt daran abarbeiten zu können.

* https://www.youtube.com/watch?v=YnWhqhNdYyk

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> Schon komisch, dass mir C++ jüngst durch immer aggressiveres Marketing
> auffällt. Hier auch wieder. Ich denke: Wer austeilt ("We stopped
> teaching C" *) muss auch einstecken können.

Ja, das zitiere ich sehr gerne. Und den unten von Dir verlinkten Vortrag 
von Kate. Wer aber aufmerksam zuhört, wird feststellen, dass es nicht 
darum geht, mit der Sprache C aufzuhören ...

> Ein gutes Produkt hat sowas jedenfalls nicht nötig und würde Kritik
> ernst nehmen, um so die Sprache zu verbessern.

Ich bin leider nicht im Gremium: allerdings kann man sich mit 
entsprechenden Papern am Prozess beteiligen. Hier sind also die 
aufgefordert, die etwas kritisieren (pos/neg) wollen. Und das wird 
positiv aufgenommen, sofern man kompetent genug argumentiert. Acho, da 
sind ja nur Idioten im Gremium ...

> Den Stohmann, dass im Standardisierungsgremium nur Idioten am Werk sind
> könnt ihr gleich wieder einpacken, den hat "hm" hier mal auf der Wiese
> aufgestellt um sich jetzt daran abarbeiten zu können.

Ja, das ist m.E ein guter Vortrag:

> * https://www.youtube.com/watch?v=YnWhqhNdYyk

: Bearbeitet durch User
von x^2 (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Und das wird
> positiv aufgenommen, sofern man kompetent genug argumentiert.

Ich hoffe entschieden wird da nach Inhalt und nicht nach Art der 
Argumentation. Vielleicht ist das aber auch das Problem, wenn man sich 
durch die immer existierende Featuritis der Community treiben läßt. Ich 
weiß es nicht.

Jedenfalls, es war ursprünglich mal schön, dass C und C++ eine Familie 
war, wobei C im Wesentlichen eine Untermenge von C++ abbildete. Es 
ermöglichte Skalierung wobei man bei Projekten unterschiedlicher Größe 
und Einsatzbereiche "in der Familie" bleiben konnte und den Code 
wiederverwenden konnte.

Die letzten Jahre und die Richtung zeigt aber, z.B. "Deprecating 
volatile"

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r3.html

dass das kaputt gemacht wurde und wird. Im Prinzip entsteht eine völlig 
neue Sprache und man interessiert sich auch nicht mehr für das 
"gestern". Das alte und morsche, es lebe das neue... Schlüsselworte 
werden umgenutzt ("auto") oder entfernt ("volatile"), ständig neue 
hinzugefügt.

In meinen Augen begründet die Skalierbarkeit aber den großen Erfolg 
dieser Sprachfamilie: Eine hochperformante Sprachfamilie, die für 
Embedded ebenso taugt wie für Applikationsentwicklung. Wer z.B. 
ernsthaft glaubt mit STL, Streams, Exceptions, RTTI und dynamischer 
Speicherallokation sind MCUs programmierbar, hat m.M. den Verstand 
verloren oder einfach keine Ahnung - schon ein "printf" ist da oft zu 
viel. Eine solche hochdynamisch entwickelnde Sprache kann in der 
Embedded Welt keiner mehr gebrauchen, wo jahrzehntelange Konstanz und 
Kompatibilität wichtig sind. Da geht aktuell in meinen Augen extrem viel 
kaputt und ich finde das einfach Schade.

von mh (Gast)


Lesenswert?

Wie gut, dass euch niemand davon abhält das gut getestete c++98 zu 
nutzen.

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> Wilhelm M. schrieb:
>> Und das wird
>> positiv aufgenommen, sofern man kompetent genug argumentiert.
>
> Ich hoffe entschieden wird da nach Inhalt und nicht nach Art der
> Argumentation.

Genau so ist es.

> Vielleicht ist das aber auch das Problem, wenn man sich
> durch die immer existierende Featuritis der Community treiben läßt.

Die Community sind wir bzw. Du und ich.

> Die letzten Jahre

Allgemeinplatz: was genau meinst Du?

>und die Richtung zeigt aber, z.B. "Deprecating volatile"

Ja, und das war gut so: das ist eines der am wenigsten verstandenen 
Schlüsselwörter (gleich nach inline).


> Im Prinzip entsteht eine völlig
> neue Sprache und man interessiert sich auch nicht mehr für das
> "gestern".

Das stimmt nicht. Der breaking change von auto ging über Jahrzehnte.

Auf der anderen Seite wurde immer die Starrheit der Sprache vorgeworfen 
- nun haben wir aufgrund der Community den 3 Jahres Zyklus.

>Das alte und morsche, es lebe das neue... Schlüsselworte
> werden umgenutzt ("auto") oder entfernt ("volatile"), ständig neue
> hinzugefügt.

s.o., allerdings als non-breaking-change

> In meinen Augen begründet die Skalierbarkeit aber den großen Erfolg
> dieser Sprachfamilie: Eine hochperformante Sprachfamilie, die für
> Embedded ebenso taugt wie für Applikationsentwicklung. Wer z.B.
> ernsthaft glaubt mit STL, Streams, Exceptions, RTTI und dynamischer
> Speicherallokation sind MCUs programmierbar, hat m.M. den Verstand
> verloren oder einfach keine Ahnung - schon ein "printf" ist da oft zu
> viel. Eine solche hochdynamisch entwickelnde Sprache kann in der
> Embedded Welt keiner mehr gebrauchen, wo jahrzehntelange Konstanz und
> Kompatibilität wichtig sind. Da geht aktuell in meinen Augen extrem viel
> kaputt und ich finde das einfach Schade.

Ganz und gar nicht: mit dem großen Augenmerk auf Compilezeit-Computing 
haben wir extrem viel dazu gewonnen.

: Bearbeitet durch User
von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> Wer z.B.
> ernsthaft glaubt mit STL, Streams, Exceptions, RTTI und dynamischer
> Speicherallokation sind MCUs programmierbar

Gerade die STL algorithms ermöglichen es, des Spagat aus Performant und 
leserlich endlich besser hinzukriegen. Generell wird in aktuelleren 
Standards der Fokus sehr stark auf zero overhead gelegt.

Keiner zwingt dich, Streams oder dynamischen Speicher zu verwenden, 
genauso wenig wie du in C malloc oder printf verwenden musst.
Dein Rant ist schlicht unsinnig. Und ja, es ist gut dass eine neue 
Sprache entsteht, und man den Kompatibilitätquatsch nicht mitschleppen 
muss. C++ ist nun mal nicht C, enweder ich nehme das eine oder das 
andere. Alles andere führt zu Pseudo-C++, das weder Fisch noch Fleisch 
ist.

von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> Die letzten Jahre und die Richtung zeigt aber, z.B. "Deprecating
> volatile"
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r3.html

Es handelt sich dabei um einen Vorschlag. Es steht dir völlig frei, 
Gegenargumente einzureichen, wenn du ihn für Unsinn hälst.
Als "Trockenübung" kannst du ihn ja mal lesen, verstehen, und die 
Gegenargumente hier auflisten.

von Heiko L. (zer0)


Lesenswert?

MaWin schrieb:
> Und wo ist denn das Problem den Standard erst etwas strikter zu
> definieren und ihn dann aufzuweiten?
> Volle Rückwärtskompatibilität ist gegeben.
> Es wurde nichts deprecated. Lediglich erweitert.
>
> Hättest du es besser gefunden, wenn man den Standard erst komplex
> definiert und dann einen folgenschweren Fehler macht, weil man doch
> etwas übersehen hat?
> Lieber Schritt für Schritt vorgehen.

Ja, richtig, aber das doch nicht normativ! Generell wäre es schon 
bedenklich, wenn die Initiative bei einem solchen Gremium liegt.
Deswegen wäre das hier

mh schrieb:
> Also einerseits darf der Standard keine kleinen Schritte machen und
> andererseits darf der Standard nur ausgereifte Dinge übernehmen. Wie
> soll das funktionieren? Soll jeder Compiler und jede
> "Standardbibliothek" erstmal drauflos testen?

durchaus eine echte Alternative. Diskussionen und Papers sind ja schön 
und gut - es ist aber absolut absehbar, dass wenn erstmal Millionen 
Entwickler anfangen mit dem Zeug rumzuspielen, sich da noch das ein oder 
andere Problem auftun mag, das man einfach nicht auf dem Schirm hatte.
Ich wüsste nicht zu sagen, ob der schwarze Peter da nun primär beim 
Komitee liegt: Wenn man jedenfalls noch-nicht standartisierte Features 
testen will muß man zT einiges an Aufwand betreiben, um sich die Sourcen 
zu organisieren, die dann ggf. erst noch mergen, komplette Toolchain 
erstellen usw. usf. Aber vielleicht ist das ja nur bei uns so und 
überall sonst sind "normale" Entwickler an breiter Front ständig dabei, 
Feedback zu den neueren Entwicklungen zu geben. Sonst ist das Zeug 
einfach relativ schlecht erprobt und man müsste die Frage stellen, 
welche prozessualen Safeguards es denn bei der schier unmöglichen 
Aufgabe gibt, sämtliche Konsequenzen aus einer 2k-Seitigen Spezifikation 
zu erfassen. Ob es dann eine zufriedenstellende Antwort ist, dass man ja 
auch einfach Sachen, die einmal normativ gesetzt wurden, wieder 
deprecaten könne, mag jeder selbst entscheiden.

Gut ist es in der Tat, dass

mh schrieb:
> euch niemand davon abhält das gut getestete c++98 zu nutzen.

wobei 98 nun doch ein wenig alt ist. Mittlerweile sind die Features aus 
11 schon fast nutzbar!

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> ...

Wie stellst du dir das ganze vor? Beispiel:

google möchte sowas wie "move-Semantic" haben. Sie bauen etwas in clang 
ein und nutzen es in chrome und ein paar weiteren internen Projekten. 
Jetzt ist Microsoft auch unzufrieden mit auto_ptr und möchte nen Ersatz, 
hat aber andere Vorstellungen. Also bauen sie etwas in ihren Compiler 
ein und nutzen es für ihre Projekte. Beide Unternehmen stellen Probleme 
fest und fixen sie und am Ende gibt es zwei funktionierende Varianten 
als Ersatz für auto_ptr. Welche der beiden Varianten wird jetzt 
standardisiert und was ist wenn beides nicht im gcc umsetzbar ist? Was 
macht Microsoft, wenn die clang Variante ausgewählt wird? Glaubst du 
ernsthaft, die sind bereit ihre gut funktionierende Lösung zu ersetzen 
oder die clang Variante ohne eigenen Bedarf in ihren Compiler 
einzubauen? Was ist mit Dingen, die Standardlib und Compiler betreffen? 
Sollen wir mit libs leben, die nur mit einem Compiler funktionieren?

Es gibt einen Grund, warum der Prozess so ist, wie er aktuell ist. Weil 
er funktioniert. Dass dabei nicht jeder mit allen Neureungen zufrieden 
ist und Fehler gemacht werden, wird von der Allgemeinheit akzeptiert. 
Dass du mit dem Prozess unzufrieden bist, ist schlicht egal. Es gibt 
allerdings Möglichkeiten dich in den Prozess einzubringen und diese so 
offensichtlichen Fehler zu vermeiden, wenn du willst.

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Es gibt einen Grund, warum der Prozess so ist, wie er aktuell ist. Weil
> er funktioniert. Dass dabei nicht jeder mit allen Neureungen zufrieden
> ist und Fehler gemacht werden, wird von der Allgemeinheit akzeptiert.
> Dass du mit dem Prozess unzufrieden bist, ist schlicht egal. Es gibt
> allerdings Möglichkeiten dich in den Prozess einzubringen und diese so
> offensichtlichen Fehler zu vermeiden, wenn du willst.

Genau, das meinte ich. Aber das sind wir Rufer in der Wüste.

Die, die hier am lautesten lamentieren, werden sich wohl nicht 
beteiligen, sondern nur weiterhin von der Arbeit anderer leben. Das ist 
mit dem qualifizierten Reporting von bugs für den Standard an sich oder 
dem clang oder gcc genauso. Leider.

von x^2 (Gast)


Lesenswert?

vn nn schrieb:
> Gerade die STL algorithms ermöglichen es, des Spagat aus Performant und
> leserlich endlich besser hinzukriegen. Generell wird in aktuelleren
> Standards der Fokus sehr stark auf zero overhead gelegt.

Bei der STL mußt du erstmal einen eigenen Allokator schreiben um 
dynamische Speicherverwaltung loszuwerfen - und Exceptions wirst du 
überhaupt nicht los.

Wir arbeiten hier an Projekten, die müssen mit 8k Flash auskommen und 
das SRAM ist an einer Hand abgezählt. Da muss man schon mit C gut planen 
und aufpassen, wie man programmiert.

Welcher Programmierer versteht heute noch, was dynamic_cast mit sich 
bringt, wann ganz ohne Absicht hinter den Kulissen copy-by-value statt 
findet, wie Exception Handling vom Compiler umgesetzt wird, wie Lambdas 
umgesetzt werden. Die ganze Sprache ist unglaublich komplex geworden. 
Zero overhead bringt nichts, wenn ein Normalprogrammierer nicht mehr 
begreifen kann, wie er denn zero overhead erreichen kann.

Klar, niemand zwing mich zu irgendwas. Aber dann frage ich mich doch, 
warum laufen überall C++ Päpste durch die Gegend und wollen Leute 
bekehren? Dann lasst das doch, wenn das Hauptargument am Ende "mußt du 
ja nicht nehmen" ist, sobald jemand ein Problem aufzeigt. Und die 
anderen, die keine Probleme sehen lässt man ins offene Messer laufen - 
Hauptsache jemanden bekehrt.

vn nn schrieb:
> Und ja, es ist gut dass eine neue
> Sprache entsteht, und man den Kompatibilitätquatsch nicht mitschleppen
> muss.

Genau die Einstellung die ich beschrieb.

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> vn nn schrieb:
>> Gerade die STL algorithms ermöglichen es, des Spagat aus Performant und
>> leserlich endlich besser hinzukriegen. Generell wird in aktuelleren
>> Standards der Fokus sehr stark auf zero overhead gelegt.
>
> Bei der STL mußt du erstmal einen eigenen Allokator schreiben um
> dynamische Speicherverwaltung loszuwerfen

Wo genau benötigt std::array oder std::tuple einen Allocator?

> Wir arbeiten hier an Projekten, die müssen mit 8k Flash auskommen und
> das SRAM ist an einer Hand abgezählt. Da muss man schon mit C gut planen
> und aufpassen, wie man programmiert.

Sehr gut!

> Welcher Programmierer versteht heute noch, was dynamic_cast mit sich
> bringt, wann ganz ohne Absicht hinter den Kulissen copy-by-value statt
> findet, wie Exception Handling vom Compiler umgesetzt wird, wie Lambdas
> umgesetzt werden. Die ganze Sprache ist unglaublich komplex geworden.

Das ist ein Allgemeinplatz: die µC von heute sind auch komplexer als vor 
10 Jahren. Lässt Du die auch links liegen, weil komplex? Das ist doch 
Pipi-Langstrumpf-Geschwafel.

> Zero overhead bringt nichts, wenn ein Normalprogrammierer nicht mehr
> begreifen kann, wie er denn zero overhead erreichen kann.

Dann muss man ihn dahin bringen, dass er das versteht. Bzw. ihm einen 
Baukasten an die Hand geben, mit dem er zugleich fehlerfreier, 
produktiver und effektiver ist.

> Klar, niemand zwing mich zu irgendwas. Aber dann frage ich mich doch,
> warum laufen überall C++ Päpste durch die Gegend und wollen Leute
> bekehren?

Ich will Dich überhaupt nicht bekehren. Am besten bleibst Du, wo Du 
bist, und überliest ab jetzt einfach die Beiträge hier.

von mh (Gast)


Lesenswert?

x^2 schrieb:
> Klar, niemand zwing mich zu irgendwas. Aber dann frage ich mich doch,
> warum laufen überall C++ Päpste durch die Gegend und wollen Leute
> bekehren? Dann lasst das doch, wenn das Hauptargument am Ende "mußt du
> ja nicht nehmen" ist, sobald jemand ein Problem aufzeigt. Und die
> anderen, die keine Probleme sehen lässt man ins offene Messer laufen -
> Hauptsache jemanden bekehrt.
Mir geht es nicht darum, dich oder irgend jemanden zu bekehren. Ich kann 
gut damit leben, wenn es weniger C++ Entwickler gibt. Das bedeutet 
weniger Konkurrenz und es besteht keine Möglichkeit, dass ich mit dir 
zusammenarbeiten muss ;-). Mir geht es darum, deine und ähnliche 
Meinungen nicht unkommentiert im Internet stehen zu lassen. Sonst 
besteht die Möglichkeit, dass andere Leute sie lesen und unreflektiert 
übernehmen.

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Wie stellst du dir das ganze vor?

Tja, das gälte es wohl zu erarbeiten.

mh schrieb:
> Also bauen sie etwas in ihren Compiler
> ein und nutzen es für ihre Projekte. Beide Unternehmen stellen Probleme
> fest und fixen sie und am Ende gibt es zwei funktionierende Varianten
> als Ersatz für auto_ptr.

Wunderbar. Da hätte man ja echt die Wahl! Nicht, dass es nicht 
realistisch eher tausende Implementierungen von auto_ptr gäbe.
In GCC jedenfalls wurden Lambdas auch eingebaut obwohl es ja 
statement-expressions schon lange gab. Keine Ahnung, wie groß der 
Widerstand da war.

mh schrieb:
> Was ist mit Dingen, die Standardlib und Compiler betreffen?
> Sollen wir mit libs leben, die nur mit einem Compiler funktionieren?

Du hast aber schon mal eine "real existierende", "compiler-neutrale" 
Library gesehen, oder?
1
XYZ_EXPORT XYZ_STDCALL(something, void, int x[XYZ_STATIC 4] XYZ_RESTRICT, ...
Dann kommen noch Sachen dazu, wie komische ABI Issues uns schon verpufft 
das tolle "ist doch Standard" vollends. Man muss sich schon angewöhnen, 
clang-tidy zu ignorieren (oder abschalten).

mh schrieb:
> Es gibt einen Grund, warum der Prozess so ist, wie er aktuell ist. Weil
> er funktioniert.

"Funktionieren" tut auch eine Lampe mit offener Phase. Ob das nun ein 
Argument ist...

mh schrieb:
> Dass dabei nicht jeder mit allen Neureungen zufrieden
> ist und Fehler gemacht werden, wird von der Allgemeinheit akzeptiert.

Du meinst: von dir, weil es dir egal ist.
Bei der obigen Lampe muß man auch nur ein bisschen aufpassen und alles 
ist wunderbar.


mh schrieb:
> Es gibt
> allerdings Möglichkeiten dich in den Prozess einzubringen und diese so
> offensichtlichen Fehler zu vermeiden, wenn du willst.

Ach, ich denke, das Thema wird da schon durchgekaut worden sein und 
Meinungen sind Meinungen, nicht wahr?

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Heiko L. schrieb:
> In GCC jedenfalls wurden Lambdas auch eingebaut obwohl es ja
> statement-expressions schon lange gab. Keine Ahnung, wie groß der
> Widerstand da war.

Da gab es sicher gar keinen Widerspruch, weil statement-expressions und
Lambda-Ausdrücke zwei völlig verschiedene Dinge sind. Ok, Lambdas können
u.a. auch als Ersatz für statement-expressions herhalten, aber der
umgekehrte Weg ist nicht möglich.

von Heiko L. (zer0)


Lesenswert?

Yalu X. schrieb:
> Heiko L. schrieb:
>> In GCC jedenfalls wurden Lambdas auch eingebaut obwohl es ja
>> statement-expressions schon lange gab. Keine Ahnung, wie groß der
>> Widerstand da war.
>
> Da gab es sicher gar keinen Widerspruch, weil statement-expressions und
> Lambda-Ausdrücke zwei völlig verschiedene Dinge sind. Ok, Lambdas können
> u.a. auch als Ersatz für statement-expressions herhalten, aber der
> umgekehrte Weg ist nicht möglich.

Nicht 100%ig, nein. Das war auch nur ein Beispiel einer speziellen 
Lösung, die gewissermaßen subsumiert wurde.

von x^2 (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Wo genau benötigt std::array oder std::tuple einen Allocator?

Das nenne ich mal unseriös. Die sind hier:

std::vector
std::deque
std::forward_list
std::list
std::set
std::multiset
std::map
std::multimap
std::unordered_set
std::unordered_multiset
std::unordered_multimap
std::unordered_map
std::unordered_multimap

Und was da dann noch von der STL übrig bleibt hast du aufgezählt. Und 
diesen kläglichen Rest programmiert dir ein durchschnittlich begabter 
Erstsemester an einem Tag. Entsprechend nützlich ist die STL auch ohne 
dynamischen Speicher bzw. ohne einen Custom Allokator.

von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> vn nn schrieb:
>> Gerade die STL algorithms ermöglichen es, des Spagat aus Performant und
>> leserlich endlich besser hinzukriegen. Generell wird in aktuelleren
>> Standards der Fokus sehr stark auf zero overhead gelegt.
>
> Bei der STL mußt du erstmal einen eigenen Allokator schreiben um
> dynamische Speicherverwaltung loszuwerfen - und Exceptions wirst du
> überhaupt nicht los.

Bullshit. Nur weil du es nicht kannst? Wofür brauchst du bei std::array 
einen Allokator? Was hindert dich daran, das Array einfach statisch zu 
allozieren, wenn du keinen dynamischen Speicher haben willst? Was 
hindert dich daran, auf Funktionen die Exceptions werfen, zu verzichten? 
Und wenn du es dir unbedingt antun willst, was hindert dich daran, 
einfach ein klassisches C-Array zu verwenden, auch in C++?
Keiner zwingt dich, Features zu nutzen. Jedem ist klar, dass nicht jedes 
Feature überall Sinn macht.

x^2 schrieb:
> Wir arbeiten hier an Projekten, die müssen mit 8k Flash auskommen und
> das SRAM ist an einer Hand abgezählt. Da muss man schon mit C gut planen
> und aufpassen, wie man programmiert.

Und?

x^2 schrieb:
> Welcher Programmierer versteht heute noch, was dynamic_cast mit sich
> bringt, wann ganz ohne Absicht hinter den Kulissen copy-by-value statt
> findet, wie Exception Handling vom Compiler umgesetzt wird, wie Lambdas
> umgesetzt werden. Die ganze Sprache ist unglaublich komplex geworden.
> Zero overhead bringt nichts, wenn ein Normalprogrammierer nicht mehr
> begreifen kann, wie er denn zero overhead erreichen kann.

Tja, genauso wie ein ein Embedded-Entwickler wissen sollte, dass printf 
und malloc auf kleinen Systemen Tabu sind, muss er halt wissen, welche 
Features er in C++ (oder jeden anderen Sprache) nutzen kann. Kann er das 
nicht, hätte er halt was anderes lernen sollen. Oder einfach 
Wisch-App-Programmierer, dort ist Performance und Gebastel egal.

x^2 schrieb:
> Klar, niemand zwing mich zu irgendwas. Aber dann frage ich mich doch,
> warum laufen überall C++ Päpste durch die Gegend und wollen Leute
> bekehren?

Wo denn? Keiner will dich bekehren. Bleib einfach bei dem was du willst.
Nachdem du ja sowieso nix sinnvolles zur Diskussion beitragen kannst 
(nicht mal erläutern, warum das vorgeschlagene Entfernen von volatile 
nun böse ist), werden sich deine C-Kentnisse eh auch in Grenzen halten. 
Denn wer seine Programmiersprache kennt, weiß halt welche Features 
suboptimal gelöst sind. Außer natürlich, er ist ideologisch verblendet, 
und hält seinen Liebling für die Spitze der Evolution.

x^2 schrieb:
> wenn das Hauptargument am Ende "mußt du
> ja nicht nehmen" ist, sobald jemand ein Problem aufzeigt.

Weil du zu beschränkt bist um unterscheiden zu können, welche Features 
du im Embedded-Bereich nutzen kannst (und große Vorteile gegenüber C 
bieten), und welche nicht?

x^2 schrieb:
> Und die
> anderen, die keine Probleme sehen lässt man ins offene Messer laufen -
> Hauptsache jemanden bekehrt.

Bitte was?

x^2 schrieb:
> vn nn schrieb:
>> Und ja, es ist gut dass eine neue
>> Sprache entsteht, und man den Kompatibilitätquatsch nicht mitschleppen
>> muss.
>
> Genau die Einstellung die ich beschrieb.

Na, dann klär uns doch auf, wo du das Problem siehst, "volatile" zu 
eliminieren und gegen sinnvollere Sprachmittel auszutauschen? Achso, 
weil du dir dann plötzlich Gedanken machen musst, anstatt einfach 
pauschal mit volatile um dich zu werfen? Weil du dann plötzlich umlernen 
musst?

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> mh schrieb:
>> Wie stellst du dir das ganze vor?
>
> Tja, das gälte es wohl zu erarbeiten.
Also nur meckern und keine Lösung.

> Wunderbar. Da hätte man ja echt die Wahl!
Das genaue Gegenteil ist der Fall. Man kann nur noch das benutzen was 
der eine Compiler unterstützt wenn man eins der "exclusiven Features" 
nutzt.

Niemand hat etwas dagegen, dass die Compilerentwickler Extensions 
einbauen und testen. Das ist sogar sehr wichtig. Du kannst aber nicht 
erwarten, dass die in vielen großen Projekten getestet werden, weil 
niemand bereit ist die Änderungen rückgängig zu machen, wenn die 
Konkurrenz im Standard landet. Diese Test in vielen großen Projekten 
wären aber notwendig, um Probleme zu finden und zu bewerten.

Es wäre sogar nötig, dass ganz neue Softwareprojekte gestartet werden 
mit diesen experimentellen Extensions und Features, damit neue Wege 
gegangen werden können die dadurch ermöglicht werden.



> Du hast aber schon mal eine "real existierende", "compiler-neutrale"
> Library gesehen, oder?XYZ_EXPORT XYZ_STDCALL(something, void, int
> x[XYZ_STATIC 4] XYZ_RESTRICT, ...
> Dann kommen noch Sachen dazu, wie komische ABI Issues uns schon verpufft
> das tolle "ist doch Standard" vollends. Man muss sich schon angewöhnen,
> clang-tidy zu ignorieren (oder abschalten).
Klar hab ich real existierende Libs gesehen. Und das was du da 
ansprichst hat wenig mit der Sprache zu tun als mit dem System auf dem 
sie angewendet wird.


> Ach, ich denke, das Thema wird da schon durchgekaut worden sein und
> Meinungen sind Meinungen, nicht wahr?
Genau! Du hast es endlich verstanden. Die Leute, die den Standard 
entwickeln, haben sich lange damit beschäftigt und haben Ahnung von dem 
was sie tun. Der Standard beruht auf Forschung, Fakten, Tests und 
Kompromissen. Und deine Meinung ist nur eine Meinung und keine Lösung 
für irgendwas.

x^2 schrieb:
> Und was da dann noch von der STL übrig bleibt hast du aufgezählt.
Du solltest mal in den Standard gucken. Da steht noch etwas mehr drin 
als Container.

von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> Wilhelm M. schrieb:
>> Wo genau benötigt std::array oder std::tuple einen Allocator?
>
> Das nenne ich mal unseriös. Die sind hier:
> [...]
> Und was da dann noch von der STL übrig bleibt hast du aufgezählt. Und
> diesen kläglichen Rest programmiert dir ein durchschnittlich begabter
> Erstsemester an einem Tag. Entsprechend nützlich ist die STL auch ohne
> dynamischen Speicher bzw. ohne einen Custom Allokator.

Äh, du willst Features verwenden die dynamischen Speicher brauchen, aber 
ohne dynamischen Speicher zu verwenden? Aber sonst gehts noch?
Ein durchschnittlich begabter Erstsemester wird dir sagen können, dass 
du keine Ahnung hast.

von Heiko L. (zer0)


Lesenswert?

Wilhelm M. schrieb:
> Das ist ein Allgemeinplatz: die µC von heute sind auch komplexer als vor
> 10 Jahren. Lässt Du die auch links liegen, weil komplex? Das ist doch
> Pipi-Langstrumpf-Geschwafel.

Also gerade bei den gebrachten Argumenten würde ich auch zur Vorsicht 
raten. Die Feinheiten von dynamic_cast und exceptions dürften in 
höchstem Maße von der Architektur abhängig sein.
Da ist es, wenn es um wiederverwendbaren Code geht, absolut nicht 
absehbar, ob man sich nicht in eine Sackgasse manövriert und das Zeug 
auf Controller X nicht absolut unbrauchbar wird.
Das schreibe ich jetzt, auch wenn ich mich jedesmal darüber ärgere, wenn 
ich mich wieder einmal mit irgendeiner C-Library herumschlagen muss. 
Unter dem Ärger muss man einfach gestehen: Das Zeug funktioniert 
wenigstens überall "problemlos". Keine komischen Unwind-Fehler, die 
sofort das Programm terminieren. Keine uncatchbaren Exceptions oder 
unmögliche dynamic_casts wegen fehlender Key-Functions in Interfaces 
usw.

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> Das nenne ich mal unseriös. Die sind hier:

Und Du verwendest auf Deinen Systemen mit 8k Flash und - nach Deiner 
Aussage - an der Hand abgezählten Bytes RAM - einen dynamischen 
Allocator bzw. malloc oder dgl? Oh je ...

Du solltest jetzt mal an Deinem Diskussionsstil arbeiten, damit Du Dich 
nicht permanent im Kreis drehst.

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Also nur meckern und keine Lösung.

Richtig. Das zu akzeptieren nennt sich "Kritikfähigkeit".

mh schrieb:
> Klar hab ich real existierende Libs gesehen. Und das was du da
> ansprichst hat wenig mit der Sprache zu tun als mit dem System auf dem
> sie angewendet wird.

Ach so, du meinst "die Sprache", die es, im Gegensatz zu ihrem Ausdruck, 
real gar nicht gibt. Dort entsteht nämlich der Eindruck, dass es immer 
auf solche Schauer-Konstruktionen hinausläuft, wenn man eine Lib nur 
genug zwischen Compilern hin- und herschiebt. Also: Funktioniert 
eigentlich überall, aber doch nirgends. Funktioniert alles, ist trotzdem 
kaputt.
Man muss die Sache schon in ihrer "Wirklichkeit" betrachten.

mh schrieb:
> Und deine Meinung ist nur eine Meinung und keine Lösung
> für irgendwas.

Was die Fähigkeit zum freien Gedanken beweist. Wenn du Lösungen 
diskutieren wolltest, wäre wohl kaum Statements wie

mh schrieb:
> Wie gut, dass euch niemand davon abhält das gut getestete c++98 zu
> nutzen.

angebracht gewesen. Denn dazu kann man auch eine haben...

von x^2 (Gast)


Lesenswert?

vn nn schrieb:
> Na, dann klär uns doch auf, wo du das Problem siehst, "volatile" zu
> eliminieren und gegen sinnvollere Sprachmittel auszutauschen? Achso,
> weil du dir dann plötzlich Gedanken machen musst, anstatt einfach
> pauschal mit volatile um dich zu werfen? Weil du dann plötzlich umlernen
> musst?

Gut, dann will ich das mal tun: Weil man sorgsam abwägen muss, ob es den 
-Aufwand- und die -Probleme- rechtfertigt, die dadurch entstehen. Wenn 
du volatile entfernst, wird jeglicher Code der es bis heute verwendet, 
nicht mehr mit einer neuen C++ Version compilierbar sein. Ob uns das 
gefällt wie volatile funktioniert oder nicht, solchen Code gibt es 
nunmal und zwar in Massen.

Damit generierst du Arbeit (sehr viel Arbeit) überall in der Welt ODER 
du schließt diejenigen, die diese Arbeit für die Anpassung nicht leisten 
können, von der Weiterentwicklung der Sprache aus. Für diese Leute endet 
dann C++ mit der neuen Version xyz, weil sie nicht updaten können.

Es ist obendrein -unproduktive- Arbeit, da du ein Produkt nicht 
-weiterentwickelst- sondern nur wieder so -anpasst- dass es im gleichen 
Zustand wie bisher auch weiterfunktioniert. Diese Zeit fehlt dann den 
Entwicklern bei der Weiterentwicklung und Verbesserung des eigentlichen 
Produkts. So eine Sprache ist ja kein Selbstzweck.

Und das NUR weil, überspitzt gesagt, irgendein Hanswurst (pardon) 
gedacht hat, dass es statt volatile auch viel hübscher ginge und man das 
jetzt ändern müsse.

Würdest du beispielsweise Linus Torvalds schreiben: "Achja Linus, du hör 
mal, das mit dem volatile, das war doch schon immer ne blöde Idee. Pass 
auf, pass kurz Kernel und die Treiber an, dann läuft's auch unter dem 
neuen C++ Standard." - ich bin mir sicher er würde dir dafür den Kopf 
abreißen.

Das gilt sinngemäß für alle inkompatiblen Änderungen.

von x^2 (Gast)


Lesenswert?

vn nn schrieb:
> Äh, du willst Features verwenden die dynamischen Speicher brauchen, aber
> ohne dynamischen Speicher zu verwenden? Aber sonst gehts noch?
> Ein durchschnittlich begabter Erstsemester wird dir sagen können, dass
> du keine Ahnung hast.

Nein, diese Feature brauchen eben keinen dynamischen Speicher. Seit wann 
brauchen Datenstrukturen zwingend dynamischen Speicher. 
Selbstverständlich geht rein statischer Speicher. Dadurch beschränkt man 
die Kapazität z.B. einer Queue, aber der Speicher auf kleinen 
Controllern ist eben endlich und es muss entsprechend abgeschätzt und 
geplant werden.

Die STL wurde nicht für Embedded geschrieben, deswegen ja auch 
"Standard" Template Library. Und da statischer Speicher bei der STL 
nicht out-of-the-box geht, bräuchte man zusätzlich einen Allokator, der 
auf diesem arbeitet.

von mh (Gast)


Lesenswert?

x^2 schrieb:
> Und das NUR weil, überspitzt gesagt, irgendein Hanswurst (pardon)
> gedacht hat, dass es statt volatile auch viel hübscher ginge und man das
> jetzt ändern müsse.

Man merkt, dass du die Paper nicht gelesen hast oder sie nicht verstehen 
kannst oder willst.

PS: ich muss mal wieder beim Rothfüsser nachgucken wann der dritte Teil 
rauskommt ...

von DPA (Gast)


Lesenswert?

x^2 schrieb:
> Würdest du beispielsweise Linus Torvalds schreiben: "Achja Linus, du hör
> mal, das mit dem volatile, das war doch schon immer ne blöde Idee. Pass
> auf, pass kurz Kernel und die Treiber an, dann läuft's auch unter dem
> neuen C++ Standard." - ich bin mir sicher er würde dir dafür den Kopf
> abreißen.

Der linux kernel enthält kein C++, das ist alles nur C.

von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> Gut, dann will ich das mal tun: Weil man sorgsam abwägen muss, ob es den
> -Aufwand- und die -Probleme- rechtfertigt, die dadurch entstehen. Wenn
> du volatile entfernst, wird jeglicher Code der es bis heute verwendet,
> nicht mehr mit einer neuen C++ Version compilierbar sein. Ob uns das
> gefällt wie volatile funktioniert oder nicht, solchen Code gibt es
> nunmal und zwar in Massen.

Tja, genau dieser Punkt wird in dem Paper auch abgewogen. Offensichtlich 
hast du es nicht gelesen, regst dich aber trotzdem darüber auf.

x^2 schrieb:
> Damit generierst du Arbeit (sehr viel Arbeit) überall in der Welt ODER
> du schließt diejenigen, die diese Arbeit für die Anpassung nicht leisten
> können, von der Weiterentwicklung der Sprache aus. Für diese Leute endet
> dann C++ mit der neuen Version xyz, weil sie nicht updaten können.

Tja, wer nicht auf den neuen Sprachstandard wechseln will, kann ja beim 
alten bleiben.
Entweder ich will Veränderung, oder ich will sie nicht.

x^2 schrieb:
> Es ist obendrein -unproduktive- Arbeit, da du ein Produkt nicht
> -weiterentwickelst- sondern nur wieder so -anpasst- dass es im gleichen
> Zustand wie bisher auch weiterfunktioniert. Diese Zeit fehlt dann den
> Entwicklern bei der Weiterentwicklung und Verbesserung des eigentlichen
> Produkts. So eine Sprache ist ja kein Selbstzweck.

Natürlich ändert sich das Verhalten. Lies doch das PAper, bevor du dich 
darüber auslässt.

x^2 schrieb:
> Und das NUR weil, überspitzt gesagt, irgendein Hanswurst (pardon)
> gedacht hat, dass es statt volatile auch viel hübscher ginge und man das
> jetzt ändern müsse

"irgendein Hanswurst": leitender Entwickler in der Compilerentwicklung 
von Apple
Alles klar, dir sicher um Längen überlegen.

Aber wie du beim lesen des Papers sicher gemerkt hast, handelt es sich 
dabei nur um einen Draft, also einen Vorschlag. Du kannst natürlich 
jederzeit deine Meinung als Kommentar einreichen, um das Komitee davon 
zu überzeugen, dass dieser Hanswurst da Blödsinn vorgeschlagen hat.

x^2 schrieb:
> Würdest du beispielsweise Linus Torvalds schreiben: "Achja Linus, du hör
> mal, das mit dem volatile, das war doch schon immer ne blöde Idee. Pass
> auf, pass kurz Kernel und die Treiber an, dann läuft's auch unter dem
> neuen C++ Standard." - ich bin mir sicher er würde dir dafür den Kopf
> abreißen.

Im Linux-Kernel wird kein C++ verwendet, aber das weißt du sicher.
Der Kernel wird auch nach wie vor C89-kompatibel geschrieben, damit wäre 
eine ähnliche Argumentation auch für C89 vs. C99 hinfällig.
Aber ja, auch in C89 waren noch einige Dinge möglich, die in C99 oder 
C11 nicht mehr gehen. Stell dir vor, dann müsste man doch tatsächlich 
den Code anpassen, bevor man den Sprachstandard wechselt!!1!!elf
Natürlich hat man vorgesorgt, und verlangt in den Guidelines, dass der 
Code sowohl C89- als auch C99-kompatibel sein muss.

x^2 schrieb:
> Das gilt sinngemäß für alle inkompatiblen Änderungen.

Tja, ohne Änderungen gibts keine Änderungen. Und nichts nervt in C++ 
oder auch in C mehr, als dass immer noch jede Menge historisch 
gewachsener Dinge mitgeschleppt werden.

von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> Nein, diese Feature brauchen eben keinen dynamischen Speicher. Seit wann
> brauchen Datenstrukturen zwingend dynamischen Speicher.

Natürlich brauchen gewisse Datenstrukturen dynamischen Speicher, nämlich 
dann, wenn ich z.B. Elemente dynamisch (na, merkst du was?) anhängen 
will.
Will oder kann ich keinen dynamischen allozierten Speicher nutzen, muss 
ich eine Datenstruktur verwenden, die auf statisch Verwendung ausgelegt 
ist. Genau deswegen bietet die STL ja auch drölf verschiedene 
Datenstrukturen.

x^2 schrieb:
> Selbstverständlich geht rein statischer Speicher. Dadurch beschränkt man
> die Kapazität z.B. einer Queue, aber der Speicher auf kleinen
> Controllern ist eben endlich und es muss entsprechend abgeschätzt und
> geplant werden.

Richtig, deswegen bietet die STL auch solche an.

x^2 schrieb:
> Die STL wurde nicht für Embedded geschrieben, deswegen ja auch
> "Standard" Template Library. Und da statischer Speicher bei der STL
> nicht out-of-the-box geht, bräuchte man zusätzlich einen Allokator, der
> auf diesem arbeitet.

Bullshit.

Nochmal: std::array.
std::vector bietet dynamisches Anhängen von Elementen, das geht nunmal 
nicht rein statisch.
std::list ist eine doppelt verkettete Liste, wenn du RAM-Bytes zählen 
musst also ohnehin das falsche Werkzeug.

Du versuchst wahrscheinlich auch, einen Nagel mit dem Schraubendreher 
einzuschlagen, und wunderst dich, dass das nicht vernünftig geht, und 
beschließt, dass der ganze Werkzeugkasten deswegen Müll ist.

Aber bitte, deine Meinung sei dir unbenommen. Ich frage mich nur, warum 
versuchst du hier zu missionieren?

von Yalu X. (yalu) (Moderator)


Lesenswert?

vn nn schrieb:
> Bullshit.
>
> Nochmal: std::array.
> std::vector bietet dynamisches Anhängen von Elementen, das geht nunmal
> nicht rein statisch.
> std::list ist eine doppelt verkettete Liste, wenn du RAM-Bytes zählen
> musst also ohnehin das falsche Werkzeug.

Was "x^2" verwenden möchte, ist bspw. ein std::vector mit variabler
size, aber konstanter, zur Compilezeit festgelegter capacity.
Entsprechdes kann man sich auch für andere Container, wie bspw.
std::deque vorstellen. Auch std::list ist mit statischem Speicher
möglich, wenn man man den Allocator so schreibt, dass er die Elemente
aus einem vorgegebenen Pool (bspw. als std::array implementiert) nimmt.

Das alles ist auch für kleine µC realisierbar, aber man muss eben etwas
Arbeit hineinstecken, die einem die Standardbibliothek nicht abnimmt.

von Vincent H. (vinci)


Lesenswert?

Yalu X. schrieb:
> Was "x^2" verwenden möchte, ist bspw. ein std::vector mit variabler
> size, aber konstanter, zur Compilezeit festgelegter capacity.

P0843:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0843r3.html

von Wilhelm M. (wimalopaan)


Lesenswert?

Vincent H. schrieb:
> Yalu X. schrieb:
>> Was "x^2" verwenden möchte, ist bspw. ein std::vector mit variabler
>> size, aber konstanter, zur Compilezeit festgelegter capacity.
>
> P0843:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0843r3.html

Aber nicht doch: das ist doch, wie "x^2" sagt, eine Aufgabe für 
Erstsemester:

https://github.com/gnzlbg/static_vector

von Vincent H. (vinci)


Lesenswert?

Wilhelm M. schrieb:
> Vincent H. schrieb:
>> Yalu X. schrieb:
>>> Was "x^2" verwenden möchte, ist bspw. ein std::vector mit variabler
>>> size, aber konstanter, zur Compilezeit festgelegter capacity.
>>
>> P0843:
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0843r3.html
>
> Aber nicht doch: das ist doch, wie "x^2" sagt, eine Aufgabe für
> Erstsemester:
>
> https://github.com/gnzlbg/static_vector

Im Vergleich zu einer Standard-konformen std::tuple Implementierung 
könnt er damit sogar recht haben. :D

von Yalu X. (yalu) (Moderator)


Lesenswert?

Vincent H. schrieb:
> P0843:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0843r3.html

Ja, genau so etwas meinte ich (und vermutlich auch "x^y"). Mehr von der
Sorte, dann erkennen vielleicht irgendwann sogar die Autobauer, dass es
eine modernere Alternative zu C89 gibt :)

von guest (Gast)


Lesenswert?

Yalu X. schrieb:
> Mehr von der
> Sorte, dann erkennen vielleicht irgendwann sogar die Autobauer, dass es
> eine modernere Alternative zu C89 gibt :)

Ach, das haben die schon vor einer ganzen Weile erkannt. Wirklich in 
purem C programiert da heute kaum noch jemand.

von Yalu X. (yalu) (Moderator)


Lesenswert?

guest schrieb:
> Yalu X. schrieb:
>> Mehr von der
>> Sorte, dann erkennen vielleicht irgendwann sogar die Autobauer, dass es
>> eine modernere Alternative zu C89 gibt :)
>
> Ach, das haben die schon vor einer ganzen Weile erkannt. Wirklich in
> purem C programiert da heute kaum noch jemand.

Wirklich?

Ich meine jetzt nicht in Infotainmentsystemen, wo fette Prozessoren und
ausgewachsene Betriebssysteme zum Einsatz kommen, sondern in den
Motorsteuergeräten, einfachen Fahrassistenzsystemen und dergleichen, wo
das meiste bare-metal programmiert wird.

Das letzte Mal, als ich in dem Bereich zu tun hatte, wäre jemand
gesteinigt worden, der das Wort "C++" auch nur geflüstert hätte. Das ist
zwar schon ein paar Jahre her, aber ein paar Jahre sind in der
Autoindustrie eine kurze Zeit, da bewegt sich üblicherweise nicht so arg
viel.

von x^2 (Gast)


Lesenswert?

vn nn schrieb:
> Natürlich brauchen gewisse Datenstrukturen dynamischen Speicher, nämlich
> dann, wenn ich z.B. Elemente dynamisch (na, merkst du was?) anhängen
> will.

Nein, brauchen sie nicht. Man kann jede Datenstruktur für statischen 
Speicher implementieren. Ich brauche da nichts merken, ich arbeite im 
Embedded Bereich seit über 10 Jahren, wir machen das täglich. Haben 
eigene Implementierungen für Queues, Maps, Trees, ... basierend auf 
-statischem Speicher-

Yalu hat's oben erklärt.


> Will oder kann ich keinen dynamischen allozierten Speicher nutzen, muss
> ich eine Datenstruktur verwenden, die auf statisch Verwendung ausgelegt
> ist. Genau deswegen bietet die STL ja auch drölf verschiedene
> Datenstrukturen.

Und genau diese drölf verschiedenen arbeiten mit dynamischem Speicher 
und deshalb bräuchte man einen Allokator dafür. Und wie schon gesagt, 
Exceptions kann man in Airbag-Steuergeräten und Co auch nicht 
gebrauchen.

Mir ist bekannt, dass Linux auf C basiert, das war überhaupt nicht der 
Zusammenhang: Großes Projekt = viel Anpassungsarbeit.


vn nn schrieb:
> Natürlich ändert sich das Verhalten. Lies doch das PAper, bevor du dich
> darüber auslässt.

Das ist ja noch schlimmer, wenn sich das Verhalten ändert: Dann reicht 
ja noch nicht mal Textersetzung A->B, sondern man darf jede einzelne 
Komponente überarbeiten und wieder die korrekte Funktion durchtesten 
damit es mit der neuen C++ Version funktioniert.

Ich frage mich im übrigen, ob hier irgendwer nach Normen und 
Zertifizierungen arbeitet: Als ob man das ganze Projekt jeden Freitag 
auf 180 Grad zieht, um die neuen Features vom Hanswurst mit bedeutender 
Funktion bei Apple einzupflegen, und dann Montag an den Kunden 
ausliefert.


Vincent H. schrieb:
> P0843:
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0843r3.html

Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded 
gebrauchen.

von mh (Gast)


Lesenswert?

x^2 schrieb:
> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
> gebrauchen.

Hast du dir das Paper angeguckt? Es werden keine Exceptions geworfen ...

von guest (Gast)


Lesenswert?

Yalu X. schrieb:
> Ich meine jetzt nicht in Infotainmentsystemen, wo fette Prozessoren und
> ausgewachsene Betriebssysteme zum Einsatz kommen, sondern in den
> Motorsteuergeräten, einfachen Fahrassistenzsystemen und dergleichen, wo
> das meiste bare-metal programmiert wird.

Da steckt am Ende zwar noch viel C Code drin, aber geschätzt 90% davon 
fallen aus irgendwelchen Codegeneratoren ala Simulink/Matlab. So richtig 
zu Fuß tut sich das kaum noch jemand an.
In den Infotainmentsystemen steckt dann eher Java :)

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> x^2 schrieb:
>> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
>> gebrauchen.
>
> Hast du dir das Paper angeguckt? Es werden keine Exceptions geworfen ...

Nur um des Arguments willen: Was wären die vom Standard garantierten 
Constraints bezgl. der Objektgröße? O(n)?

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> mh schrieb:
>> x^2 schrieb:
>>> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
>>> gebrauchen.
>>
>> Hast du dir das Paper angeguckt? Es werden keine Exceptions geworfen ...
>
> Nur um des Arguments willen: Was wären die vom Standard garantierten
> Constraints bezgl. der Objektgröße? O(n)?

42?! Wovon redest du?

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Heiko L. schrieb:
>> mh schrieb:
>>> x^2 schrieb:
>>>> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
>>>> gebrauchen.
>>>
>>> Hast du dir das Paper angeguckt? Es werden keine Exceptions geworfen ...
>>
>> Nur um des Arguments willen: Was wären die vom Standard garantierten
>> Constraints bezgl. der Objektgröße? O(n)?
>
> 42?! Wovon redest du?

Das könnte hinkommen.
Ich spreche davon, dass viele der STL Klassen für embedded ziemlich 
ungeeignet sein dürften, da sie halt auf die häufigsten Use-Cases 
getrimmt sind und daher ggf. keine ausreichenden Garantien bezgl. ihres 
Speicherbedarfs machen.
Es gibt z.B. noch nicht einmal eine Wrapper-Klasse für (const) char*, 
die wirklich einfach nur den einen Pointer verwaltet und ein wenig 
syntaktischen Sugar für string-operationen bietet. Und das dann auch 
immer noch als size_t. Jeder Container schleppt seinen Allocator mit 
herum usw.
Wenn ich mir da so einen 2 Ct. Mikro mit 64 Byte Speicher vorstelle, 
passt das nicht. Man sieht sofort, dass ein size_t reine Verschwendung 
ist.

Edit: "Häufigster Use-Case" - bei den ganzen Embedded Geräten, müsste 
man das evtl. neu definieren.

: Bearbeitet durch User
von x^2 (Gast)


Lesenswert?

mh schrieb:
> x^2 schrieb:
>> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
>> gebrauchen.
>
> Hast du dir das Paper angeguckt? Es werden keine Exceptions geworfen ...

Sorry, hast recht: Hatte es überflogen und Kapital 4.4 Exception Safety 
so verstanden und dann aufgehört. Er erläutert darin aber nur welche 
Exceptions bei den Methoden denkbar -wären-, sagt aber erst am Ende 
dazu, dass das so nicht sein soll. Gemein :-)

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> Ich spreche davon, dass viele der STL Klassen für embedded ziemlich
> ungeeignet sein dürften, da sie halt auf die häufigsten Use-Cases
> getrimmt sind und daher ggf. keine ausreichenden Garantien bezgl. ihres
> Speicherbedarfs machen.
Welche Garantien? Was für ein Speicherbedarf? Wer ist schuld, wenn deine 
Stdlib nicht für deinen Usecase optimiert ist? Der Standard, oder du 
weil du nicht die richtige Lib ausgesucht hast?

Heiko L. schrieb:
> Wenn ich mir da so einen 2 Ct. Mikro mit 64 Byte Speicher vorstelle,
> passt das nicht. Man sieht sofort, dass ein size_t reine Verschwendung
> ist.

1.) Wie groß ist ein std::size_t auf deinem 64 Byte Mikro?
2.) Warum ist das beim aktuellen Thema wichtig?

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Heiko L. schrieb:
>> Ich spreche davon, dass viele der STL Klassen für embedded ziemlich
>> ungeeignet sein dürften, da sie halt auf die häufigsten Use-Cases
>> getrimmt sind und daher ggf. keine ausreichenden Garantien bezgl. ihres
>> Speicherbedarfs machen.
> Welche Garantien? Was für ein Speicherbedarf? Wer ist schuld, wenn deine
> Stdlib nicht für deinen Usecase optimiert ist? Der Standard, oder du
> weil du nicht die richtige Lib ausgesucht hast?
>
> Heiko L. schrieb:
>> Wenn ich mir da so einen 2 Ct. Mikro mit 64 Byte Speicher vorstelle,
>> passt das nicht. Man sieht sofort, dass ein size_t reine Verschwendung
>> ist.
>
> 1.) Wie groß ist ein std::size_t auf deinem 64 Byte Mikro?
> 2.) Warum ist das beim aktuellen Thema wichtig?

Jetzt kommt Poker:
1
According to the 1999 ISO C standard (C99), size_t is an unsigned integer type of at least 16 bit (see sections 7.17 and 7.18.3).

Was glaubst du, wie groß der ist?

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> Jetzt kommt Poker:
> According to the 1999 ISO C standard (C99), size_t is an unsigned
> integer type of at least 16 bit (see sections 7.17 and 7.18.3).
>
> Was glaubst du, wie groß der ist?

Ich kann dir ne untere Grenze geben ...
Was hat das mit dem Thema zu tun?

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Heiko L. schrieb:
>> Jetzt kommt Poker:
>> According to the 1999 ISO C standard (C99), size_t is an unsigned
>> integer type of at least 16 bit (see sections 7.17 and 7.18.3).
>>
>> Was glaubst du, wie groß der ist?
>
> Ich kann dir ne untere Grenze geben ...
> Was hat das mit dem Thema zu tun?

War das eine Antwort?

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> War das eine Antwort?

Soll ich ne Zahl erfinden? Und warum muss ich auf Fragen antworten, du 
aber nicht?

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Heiko L. schrieb:
>> War das eine Antwort?
>
> Soll ich ne Zahl erfinden? Und warum muss ich auf Fragen antworten, du
> aber nicht?

Oh je....

von mh (Gast)


Lesenswert?

Heiko L. schrieb:
> mh schrieb:
>> Heiko L. schrieb:
>>> War das eine Antwort?
>>
>> Soll ich ne Zahl erfinden? Und warum muss ich auf Fragen antworten, du
>> aber nicht?
>
> Oh je....

Was ist los? Ist der Groschen gefallen und du hast verstanden warum 
size_t für einen Container irrelevant ist? Unwahrscheinlich ...

von Heiko L. (zer0)


Lesenswert?

mh schrieb:
> Heiko L. schrieb:
>> mh schrieb:
>>> Heiko L. schrieb:
>>>> War das eine Antwort?
>>>
>>> Soll ich ne Zahl erfinden? Und warum muss ich auf Fragen antworten, du
>>> aber nicht?
>>
>> Oh je....
>
> Was ist los? Ist der Groschen gefallen und du hast verstanden warum
> size_t für einen Container irrelevant ist? Unwahrscheinlich ...

Welche?

von Philipp Klaus K. (pkk)


Lesenswert?

vn nn schrieb:
> x^2 schrieb:
>> Die letzten Jahre und die Richtung zeigt aber, z.B. "Deprecating
>> volatile"
>>
>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r3.html
>
> Es handelt sich dabei um einen Vorschlag. Es steht dir völlig frei,
> Gegenargumente einzureichen, wenn du ihn für Unsinn hälst.
> Als "Trockenübung" kannst du ihn ja mal lesen, verstehen, und die
> Gegenargumente hier auflisten.

Nein, wie man dem Protokoll 
(http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/n4826.pdf) 
entnehmen kann, wurde der Vorschlag bereits angenommen:

> Motion 19
> Move to apply the changes in P1152R4 (Deprecating volatile) to the C++ working 
paper.
> There are objections in the room.
> In favour : 63
> Opposed : 1
> Abstain : 7
> Motion passes.

von mh (Gast)


Lesenswert?

Philipp Klaus K. schrieb:
> Nein, wie man dem Protokoll
> (http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/n4826.pdf)
> entnehmen kann, wurde der Vorschlag bereits angenommen:
>
>> Motion 19
>> Move to apply the changes in P1152R4 (Deprecating volatile) to the C++ working
> paper.
>> There are objections in the room.
>> In favour : 63
>> Opposed : 1
>> Abstain : 7
>> Motion passes.

Der Schritt kann rückgängig gemacht werden ...

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Philipp Klaus K. schrieb:
>> Nein, wie man dem Protokoll
>> (http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/n4826.pdf)
>> entnehmen kann, wurde der Vorschlag bereits angenommen:
>>
>>> Motion 19
>>> Move to apply the changes in P1152R4 (Deprecating volatile) to the C++ working
>> paper.
>>> There are objections in the room.
>>> In favour : 63
>>> Opposed : 1
>>> Abstain : 7
>>> Motion passes.
>
> Der Schritt kann rückgängig gemacht werden ...

Ist im gcc-trunk (10) schon seit ca. 6 Wochen drin.

von Philipp Klaus K. (pkk)


Lesenswert?

x^2 schrieb:
> Jedenfalls, es war ursprünglich mal schön, dass C und C++ eine Familie
> war, wobei C im Wesentlichen eine Untermenge von C++ abbildete. Es
> ermöglichte Skalierung wobei man bei Projekten unterschiedlicher Größe
> und Einsatzbereiche "in der Familie" bleiben konnte und den Code
> wiederverwenden konnte.
>
> Die letzten Jahre und die Richtung zeigt aber, z.B. "Deprecating
> volatile"
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1152r3.html
>
> dass das kaputt gemacht wurde und wird. Im Prinzip entsteht eine völlig
> neue Sprache und man interessiert sich auch nicht mehr für das
> "gestern". Das alte und morsche, es lebe das neue... Schlüsselworte
> werden umgenutzt ("auto") oder entfernt ("volatile"), ständig neue
> hinzugefügt.

Mit P1152 bin ich nicht vertraut. In R0 hieß es noch "WG14 should be 
consulted"; da könnte man versuchen, herauszufinden, ob und mit welchem 
Ergebnis das geschah.

Ansonsten ist mein Eindruck, dass WG14 und WG21 durchaus noch Interesse 
haben, dass sich die Sprachen nicht unnötig auseinanderentwickeln; 
insbesondere auf die Möglichkeit, Header zu schreiben, die man sowohl in 
C als auch in C++ nutzen kann, wird Wert gelegt.

Dass C2X für Attribute die C++-Syntax übernommen hat, und _Static_assert 
mit 2 Argumentes sind aktuelle Beispiele dafür.

Auch bei der Unterstützung von Unicode und bei memory model / pointer 
provenance wird koordiniert.

Philipp

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Ist im gcc-trunk (10) schon seit ca. 6 Wochen drin.

Ich sag nicht, dass das einfach ist. Aber falls jemand gute Argumente 
hat, ist es möglich. Neue und gute Argumente gegen das Paper werden wir 
hier siche nicht sehen.

Aber danke für den Hinweis. Ich werd nachher mal testen was der gcc mit 
meinen 2 oder 3 volatiles macht.

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Aber danke für den Hinweis. Ich werd nachher mal testen was der gcc mit
> meinen 2 oder 3 volatiles macht.

Vermutlich betrifft es "nur" die compound-assignments.

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> mh schrieb:
>> Aber danke für den Hinweis. Ich werd nachher mal testen was der gcc mit
>> meinen 2 oder 3 volatiles macht.
>
> Vermutlich betrifft es "nur" die compound-assignments.

Die Doku sagt
1
Several C++20 features have been implemented:
2
P1152R4, Deprecating volatile
keine Einschränkung.

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Wilhelm M. schrieb:
>> mh schrieb:
>>> Aber danke für den Hinweis. Ich werd nachher mal testen was der gcc mit
>>> meinen 2 oder 3 volatiles macht.
>>
>> Vermutlich betrifft es "nur" die compound-assignments.
>
> Die Doku sagt
>
1
> Several C++20 features have been implemented:
2
> P1152R4, Deprecating volatile
3
>
> keine Einschränkung.

Schon. Ich bezog das nur auf Deinen Code. Es sei denn, Du hast UDT mit 
volatile-Elementfunktionen.

von vn nn (Gast)


Lesenswert?

x^2 schrieb:
> vn nn schrieb:
>> Natürlich brauchen gewisse Datenstrukturen dynamischen Speicher, nämlich
>> dann, wenn ich z.B. Elemente dynamisch (na, merkst du was?) anhängen
>> will.
>
> Nein, brauchen sie nicht. Man kann jede Datenstruktur für statischen
> Speicher implementieren. Ich brauche da nichts merken, ich arbeite im
> Embedded Bereich seit über 10 Jahren, wir machen das täglich. Haben
> eigene Implementierungen für Queues, Maps, Trees, ... basierend auf
> -statischem Speicher-
>
> Yalu hat's oben erklärt.

Tja, und du wunderst dich nun, dass man Spezialfälle nicht mit 
Standardlibraries abdecken kann? Ist ja nicht so, dass es sowas in C out 
of the box gäbe...

x^2 schrieb:
> Und genau diese drölf verschiedenen arbeiten mit dynamischem Speicher
> und deshalb bräuchte man einen Allokator dafür. Und wie schon gesagt,
> Exceptions kann man in Airbag-Steuergeräten und Co auch nicht
> gebrauchen.

Ja dann nutz die doch einfach nicht? Du nutzt doch auch in C kein 
malloc?
Und wenn du eine verlinkte Liste ohne dynamischen Speicher haben willst, 
kannst du sie ja entweder komplett selbst implementieren wie in C, oder 
du leitest dir halt was von std::list ab. Wo ist dein Problem?
Oder noch besser, du nutzt einfach gar kein C++.

x^2 schrieb:
> Mir ist bekannt, dass Linux auf C basiert, das war überhaupt nicht der
> Zusammenhang: Großes Projekt = viel Anpassungsarbeit.

Ja, die hab ich immer, wenn ich von einem Sprachstandard auf den anderen 
wechsle. Will ich das nicht, wechsle ich halt nicht. Von C89 auf C11 mag 
unter Umständen auch mit viel Anpassungsarbeit verbunden sein.
Viel schlimmer in dem Zusammenhang: dass du die Papers, die du 
verlinkst, offensichtlich nicht mal weiter als bis zum Titel liest.
Vermutlich hast du auch nicht verstanden, dass "deprecated" nicht heißt, 
dass es von jetzt auf gleich raus fliegt. Selbst wenn der Vorschlag es 
also in C++20 schaffen würde, würde es erst mimt 23 oder noch später 
wirklich rausfliegen.

x^2 schrieb:
> vn nn schrieb:
>> Natürlich ändert sich das Verhalten. Lies doch das PAper, bevor du dich
>> darüber auslässt.
>
> Das ist ja noch schlimmer, wenn sich das Verhalten ändert: Dann reicht
> ja noch nicht mal Textersetzung A->B, sondern man darf jede einzelne
> Komponente überarbeiten und wieder die korrekte Funktion durchtesten
> damit es mit der neuen C++ Version funktioniert.

Welchen Sinn hat ein neuer Sprachstandard, wenn sich nix ändert?
Entweder ich will Veränderung, oder eben nicht. Man wechselt ja auch 
nicht einfach mitten in einem laufenden Projekt des wechselns willen.

x^2 schrieb:
> Ich frage mich im übrigen, ob hier irgendwer nach Normen und
> Zertifizierungen arbeitet: Als ob man das ganze Projekt jeden Freitag
> auf 180 Grad zieht, um die neuen Features vom Hanswurst mit bedeutender
> Funktion bei Apple einzupflegen, und dann Montag an den Kunden
> ausliefert

Ich weiß ja nicht, ob du schonmal irgendwo nach Normen und 
Zertifizierungen gearbeitet hast, aber kein Mensch wechselt einfach so 
zum Spaß von jeden Freitag den Sprachstandard.
Man upgradet ja auch nicht einfach zum Spaß drei Tage vor Auslieferung 
von C89 auf C99 oder von C99 auf C11, warum sollte man dann einfach so 
zum Spaß von C++11 auf C++20 wechseln? Drei Tage vor Auslieferung würd 
ich nicht mal ein Compilerupdate machen...
Ich frag mich echt, wo deine komplett praxisfernen Vorstellungen 
herkommen?

mh schrieb:
> x^2 schrieb:
>> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
>> gebrauchen.
>
> Hast du dir das Paper angeguckt? Es werden keine Exceptions geworfen ...

Lesen ist nicht seine Stärke.

Heiko L. schrieb:
> Ich spreche davon, dass viele der STL Klassen für embedded ziemlich
> ungeeignet sein dürften, da sie halt auf die häufigsten Use-Cases
> getrimmt sind und daher ggf. keine ausreichenden Garantien bezgl. ihres
> Speicherbedarfs machen.

Ein komplett statischer Container wir std::array braucht natürlich 
keinen Overhead, wofür auch? Auch std::static_vector wird nicht mehr 
brauchen, als wenn du selbst sowas zu Fuß implementierst.
Aber natürlich braucht ein Container mit irgendwelchen dynamischen 
Features mehr Overhead als ein klassiches C-Array[] oder ein std::array, 
egal ob du es nun in C zu Fuß implementierst, oder dein Compilerbauer 
für dich in die STL packt.
Wie so oft in C++ oder auch in C ist sowas natürlich vom Compilerbauer 
und von der Zielplattform abhängig. Auch in C kann für viele Dinge nach 
oben hin nicht garantiert werden. Aber man kann mal davon ausgehen, dass 
weder beim gcc, noch clang oder MSVC anfänger sitzen, und sie die Dinge 
schon mindestens so effizient implementieren wie du zu Fuß. Die 
Compilerotimierung erledigt dann den Rest.
Und ja, Resourceneffizient ist bei C++ immer ein Thema gewesen, auf das 
geachtet wurde. Natürlich hält dich aber keiner ab, einen absolut 
ineffizienten Compiler zu bauen, tut in C aber auch keiner.

Heiko L. schrieb:
> Jeder Container schleppt seinen Allocator mit
> herum usw.
> Wenn ich mir da so einen 2 Ct. Mikro mit 64 Byte Speicher vorstelle,
> passt das nicht. Man sieht sofort, dass ein size_t reine Verschwendung
> ist.

Was redest du? Nimm keinen dynamischen Container, dann hat er keinen 
Overhead. Dynamik ohne Overhead geht halt nicht.

Heiko L. schrieb:
> Jetzt kommt Poker:
> According to the 1999 ISO C standard (C99), size_t is an unsigned
> integer type of at least 16 bit (see sections 7.17 and 7.18.3).
>
> Was glaubst du, wie groß der ist?

Ja und nu? Was hat das nun mit C++ zu tun?

mh schrieb:
> Was ist los? Ist der Groschen gefallen und du hast verstanden warum
> size_t für einen Container irrelevant ist? Unwahrscheinlich ...

Was faselst du die ganze Zeit von size_t und Containern?

Philipp Klaus K. schrieb:
> Nein, wie man dem Protokoll
> (http://open-std.org/JTC1/SC22/WG21/docs/papers/2019/n4826.pdf)
> entnehmen kann, wurde der Vorschlag bereits angenommen:
>
>> Motion 19
>> Move to apply the changes in P1152R4 (Deprecating volatile) to the C++ working
> paper.
>> There are objections in the room.
>> In favour : 63
>> Opposed : 1
>> Abstain : 7
>> Motion passes.

Oh, tatsächlich. Hoppala, mein Fehler. Na immerhin ist scheinbar nicht 
nur "irgendein Depp bei Apple" dafür, um mal bei x^2's Wortlaut zu 
bleiben. Aber sicher ist er der Meinung, dass auch die 62 anderen 
Mitglieder des Komitees keine Ahnung haben, und er als einziger den 
Durchblick hat.

von Wilhelm M. (wimalopaan)


Lesenswert?

vn nn schrieb:
> Was faselst du die ganze Zeit von size_t und Containern?

Ich denke, er meint die compiletime-reflection, die wir von 
std-containern gewohnt sind via size_type, value_type, und den anderen 
traits.

Auf einem µC macht es bspw. durchaus Sinn, bei einer Array<T, 
Size>-Implementierung für size_type nur uint8_t zu deklarieren, wenn 
(Size < 256) ist, andernfalls uint16_t bzw. uint32_t bei Size > 65535.

von vn nn (Gast)


Lesenswert?

Wilhelm M. schrieb:
> vn nn schrieb:
>> Was faselst du die ganze Zeit von size_t und Containern?
>
> Ich denke, er meint die compiletime-reflection, die wir von
> std-containern gewohnt sind via size_type, value_type, und den anderen
> traits.

Bei statischen Containern wird das ja eh wegoptimiert:
1
    std::array<uint8_t, 4> foo{ {1, 2, 3, 4} };
2
    size_t bar = foo.size();
3
4
wird zu
5
6
        ldr     r3, .L5
7
        ldr     r3, [r3]
8
        str     r3, [fp, #-12]
9
        mov     r3, #4
10
        str     r3, [fp, #-8]
11
.L5:
12
        .word   .LC0
13
.LC0:
14
        .byte   1
15
        .byte   2
16
        .byte   3
17
        .byte   4
18
19
ARM gcc 8.3.1

Dynamische Container machen bei so wenig RAM ohnehin keinen Sinn.

Wilhelm M. schrieb:
> Auf einem µC macht es bspw. durchaus Sinn, bei einer Array<T,
> Size>-Implementierung für size_type nur uint8_t zu deklarieren, wenn
> (Size < 256) ist, andernfalls uint16_t bzw. uint32_t bei Size > 65535.

Wie stellst du dir vor, dass das Funktionieren soll? Damit würde man 
sich jede Menge neuer Probleme aufreissen, für eine Standardbibliothek 
völlig ungeeignet...

Beitrag #6028134 wurde vom Autor gelöscht.
von Vincent H. (vinci)


Lesenswert?

vn nn schrieb:
> Wie stellst du dir vor, dass das Funktionieren soll? Damit würde man
> sich jede Menge neuer Probleme aufreissen, für eine Standardbibliothek
> völlig ungeeignet...

So zum Beispiel:
1
using uint8 = std::numeric_limits<uint8_t>;
2
using uint16 = std::numeric_limits<uint16_t>;
3
using uint32 = std::numeric_limits<uint32_t>;
4
5
template<uint64_t Max, typename = std::enable_if_t<Max >= 0u>>
6
using smallest_unsigned_t = std::conditional_t<
7
  Max <= uint8::max(),
8
  uint8_t,
9
  std::conditional_t<
10
    Max <= uint16::max(),
11
    uint16_t,
12
    std::conditional_t<Max <= uint32::max(), uint32_t, uint64_t>>>;

Welche Probleme sollen das sein?
size_type bleibt natürlich weiterhin size_t, nur wozu soll ein Container 
mit weniger als 256 Elementen dessen Größe in einem size_t speichern?

von Wilhelm M. (wimalopaan)


Lesenswert?

Vincent H. schrieb:
> vn nn schrieb:
>> Wie stellst du dir vor, dass das Funktionieren soll? Damit würde man
>> sich jede Menge neuer Probleme aufreissen, für eine Standardbibliothek
>> völlig ungeeignet...
>
> So zum Beispiel:
>
>
1
> using uint8 = std::numeric_limits<uint8_t>;
2
> using uint16 = std::numeric_limits<uint16_t>;
3
> using uint32 = std::numeric_limits<uint32_t>;
4
> 
5
> template<uint64_t Max, typename = std::enable_if_t<Max >= 0u>>
6
> using smallest_unsigned_t = std::conditional_t<
7
>   Max <= uint8::max(),
8
>   uint8_t,
9
>   std::conditional_t<
10
>     Max <= uint16::max(),
11
>     uint16_t,
12
>     std::conditional_t<Max <= uint32::max(), uint32_t, uint64_t>>>;
13
>

Das enable_if kannst Du Dir bei Deinem uint sparen ;-)

> Welche Probleme sollen das sein?

es wäre halt ein nicht-ganz std konformer Container, der size_type 
abhängig von der Größe deklariert.

1
XYZ::array<char, 100> a1{};
2
const auto l1 = a1.size();
3
static_assert(std::is_same_v<decltype(l1), uint8_t>);
4
5
XYZ::array<char, 1000> a2{};
6
const auto l2 = a2.size();
7
static_assert(std::is_same_v<decltype(l2), uint16_t>);

Für generischen Code macht das durchaus einen Unterschied.

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Schon. Ich bezog das nur auf Deinen Code. Es sei denn, Du hast UDT mit
> volatile-Elementfunktionen.

Ahh. Ich erwarte keine Probleme ;-)

> mh schrieb:
>> x^2 schrieb:
>>> Jetzt macht man noch die Exceptions raus, dann kann man's für Embedded
>>> gebrauchen.
Ich versuche nur aus Heiko heruszukitzeln, was er mit seinen size_t 
will. Aber er antwortet nicht ...

vn nn schrieb:
> Wilhelm M. schrieb:
>> Auf einem µC macht es bspw. durchaus Sinn, bei einer Array<T,
>> Size>-Implementierung für size_type nur uint8_t zu deklarieren, wenn
>> (Size < 256) ist, andernfalls uint16_t bzw. uint32_t bei Size > 65535.
>
> Wie stellst du dir vor, dass das Funktionieren soll? Damit würde man
> sich jede Menge neuer Probleme aufreissen, für eine Standardbibliothek
> völlig ungeeignet...

Für eine allgemeine Stdlib ist das sicher nicht geeignet. Aber für eine 
auf sehr kleine CPUs optimierte Lib sieht das villeicht etwas anders 
aus. Heiko ist sicher bereit nen Haufen Geld auszugeben, damit sein 
std::vector ein oder zwie Byte weniger braucht auf seinem "64 Byte 
Mikro" ... (falls der vector nicht aus 3 Pointern besteht)

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Für eine allgemeine Stdlib ist das sicher nicht geeignet.

Stimmt bedingt.

Da es ja bspw. für die kleinen AVR 8-Bitter keine stdlibc++ gibt, habe 
ich schon seit Jahren eine eigene Implementierung, die in diesen 
Aspekten von der stdlib abweicht. Und hier kommt kann 
compiletime-refection zur vollen Ausprägung, womit der Assembler-Code 
immer optimal ist.

von vn nn (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Da es ja bspw. für die kleinen AVR 8-Bitter keine stdlibc++ gibt

Ich hab ja schon lange nichts mehr mit AVR gemacht, aber wie siehts 
eigentlich mit AVR-Support in LLVM aus, ist da was absehbar?

von Wilhelm M. (wimalopaan)


Lesenswert?

vn nn schrieb:
> Wilhelm M. schrieb:
>> Da es ja bspw. für die kleinen AVR 8-Bitter keine stdlibc++ gibt
>
> Ich hab ja schon lange nichts mehr mit AVR gemacht, aber wie siehts
> eigentlich mit AVR-Support in LLVM aus, ist da was absehbar?

War mal im Gespräch, aber aktuell eher nichts ...

von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:
> vn nn schrieb:
>> Wilhelm M. schrieb:
>>> Da es ja bspw. für die kleinen AVR 8-Bitter keine stdlibc++ gibt
>>
>> Ich hab ja schon lange nichts mehr mit AVR gemacht, aber wie siehts
>> eigentlich mit AVR-Support in LLVM aus, ist da was absehbar?
>
> War mal im Gespräch, aber aktuell eher nichts ...

Wenn man Zugriff auf EDG hat, kann man C++ -> EDG -> C -> C-Compiler 
machen, wobei der sdcc ja AVR auch nicht unterstützt. Aber so konnte ich 
meinen Z80 schonmal bestücken ;-)

von Philipp Klaus K. (pkk)


Lesenswert?

Wilhelm M. schrieb:
> Wilhelm M. schrieb:
>> vn nn schrieb:
>>> Wilhelm M. schrieb:
>>>> Da es ja bspw. für die kleinen AVR 8-Bitter keine stdlibc++ gibt
>>>
>>> Ich hab ja schon lange nichts mehr mit AVR gemacht, aber wie siehts
>>> eigentlich mit AVR-Support in LLVM aus, ist da was absehbar?
>>
>> War mal im Gespräch, aber aktuell eher nichts ...
>
> Wenn man Zugriff auf EDG hat, kann man C++ -> EDG -> C -> /C-Compiler/
> machen, wobei der sdcc ja AVR auch nicht unterstützt. Aber so konnte ich
> meinen Z80 schonmal bestücken ;-)

Ohne EDG ginge noch http://www.colecovision.eu/llvm+sdcc/, aber das ist 
noch experimentall.

von vn nn (Gast)


Lesenswert?

Vincent H. schrieb:
> vn nn schrieb:
>> Wie stellst du dir vor, dass das Funktionieren soll? Damit würde man
>> sich jede Menge neuer Probleme aufreissen, für eine Standardbibliothek
>> völlig ungeeignet...
>
> So zum Beispiel:
> using uint8 = std::numeric_limits<uint8_t>;
> using uint16 = std::numeric_limits<uint16_t>;
> using uint32 = std::numeric_limits<uint32_t>;
>
> template<uint64_t Max, typename = std::enable_if_t<Max >= 0u>>
> using smallest_unsigned_t = std::conditional_t<
>   Max <= uint8::max(),
>   uint8_t,
>   std::conditional_t<
>     Max <= uint16::max(),
>     uint16_t,
>     std::conditional_t<Max <= uint32::max(), uint32_t, uint64_t>>>;
>
> Welche Probleme sollen das sein?
> size_type bleibt natürlich weiterhin size_t, nur wozu soll ein Container
> mit weniger als 256 Elementen dessen Größe in einem size_t speichern?

Natürlich ist es machbar, mag auch durchaus sinnvoll sein. Als 
allgemeines Verhalten in einer Standardbibliothek allerdings ungeeignet, 
da ist es wesentlich sinnvoller, wenn standardmäßig einfach ein size_t 
zurückkommt.
Man kann von der STL-Implementierung ja leicht eine eigene ableiten, und 
diese auf die eigenen Bedürfnisse zuschneiden, ohne sie komplett per 
Hand stricken zu müssen wie in C.

size_t oder so ein Verhalten ist ja auch keine Spezialität von C++, ist 
ja auch in C so, dass für Speichergrößen standardmäßig mal size_t 
verwendet wird, auch wenn in konkreten Anwendungen weniger reichen 
würde.
Viel mehr noch, in C wäre derartige Template-Zauberei nicht mal möglich.

Lustig, wie hier C++ Dinge angekreidet werden, die in C genau so oder 
ähnlich sind, oder dass Dinge nicht zu 100% auf embedded getrimmt sind, 
die in C nicht mal verfügbar sind und sowieso erst per Hand 
implementiert werden müssen.
Ja klar ist std::list nicht Embedded-optimiert, aber gegenüber C, wo ich 
die komplette Implementierung per Hand erledigen muss, hab ich immer 
noch einen Vorteil.

von Wilhelm M. (wimalopaan)


Lesenswert?

Philipp Klaus K. schrieb:
>
> Ohne EDG ginge noch http://www.colecovision.eu/llvm+sdcc/, aber das ist
> noch experimentall.

Das geht nur mit der Uralt-Version <= 3.8.

von Wilhelm M. (wimalopaan)


Lesenswert?

vn nn schrieb:
> Natürlich ist es machbar, mag auch durchaus sinnvoll sein. Als
> allgemeines Verhalten in einer Standardbibliothek allerdings ungeeignet,
> da ist es wesentlich sinnvoller, wenn standardmäßig einfach ein size_t
> zurückkommt.

Nein, bei einem std::array<> wäre es m.E. in der Tat sinnvoller, man 
würde den Typ bspw. von size() adaptiv gestalten. Egal, welchen unsinged 
Typ man dort dann nimmt, er ist in jedem Fall kleiner als size_t, und 
damit wieder zuweisungskompatibel.

M.E. ist die starre Festlegung von array<>::size() auf size_t ein 
design-flaw. Aber man kann auch anderer Meinung sein aus Gründen der 
Kongruenz zu sizeof(). Außerdem hätte man sich dann auch den nested 
typ-alias size_type sparen können, wenn Größenangeben immer size_t 
sind. Aus Rückwärtskompatibilitätsgründen wird daran aber (im Moment) 
nichts geändert. Derartige Ungereimtheiten findet man auch an anderen 
Stellen.

von Wilhelm M. (wimalopaan)


Lesenswert?

vn nn schrieb:
> Lustig, wie hier C++ Dinge angekreidet werden, die in C genau so oder
> ähnlich sind, oder dass Dinge nicht zu 100% auf embedded getrimmt sind,
> die in C nicht mal verfügbar sind und sowieso erst per Hand
> implementiert werden müssen.

Oh, Du bist noch nicht lange in diesem Form, oder?

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Außerdem hätte man sich dann auch den nested
> typ-alias size_type sparen können, wenn Größenangeben immer size_t
> sind.

Ist der size_type nicht notwendig, weil std::array ein Container ist? 
Ich hab grad nicht in den Standard geguckt, aber cppreference sagt, dass 
es eine named requirement "Container" gibt mit size_type als 
requirement.

von TriHexagon (Gast)


Lesenswert?

Wilhelm M. schrieb:
> vn nn schrieb:
>> Lustig, wie hier C++ Dinge angekreidet werden, die in C genau so oder
>> ähnlich sind, oder dass Dinge nicht zu 100% auf embedded getrimmt sind,
>> die in C nicht mal verfügbar sind und sowieso erst per Hand
>> implementiert werden müssen.
>
> Oh, Du bist noch nicht lange in diesem Form, oder?

LOL stimmt, optionale Features, welche in einem bestimmten 
Anwendungsfall suboptimal sind (oder aus irgendwelchen Gründen auch 
immer abgelehnt werden), sind in diesem Forum ein handfester Nachteil. 
Das letzte Mal trat dieser Fall bei Rust mit Cargo zu, aber regelmäßig 
bei C++ wie auch hier.

von Wilhelm M. (wimalopaan)


Lesenswert?

mh schrieb:
> Wilhelm M. schrieb:
>> Außerdem hätte man sich dann auch den nested
>> typ-alias size_type sparen können, wenn Größenangeben immer size_t
>> sind.
>
> Ist der size_type nicht notwendig, weil std::array ein Container ist?
> Ich hab grad nicht in den Standard geguckt, aber cppreference sagt, dass
> es eine named requirement "Container" gibt mit size_type als
> requirement.

Naja, wenn alle(!) Container ihn zu size_t deklarieren, braucht man die 
Deklaration strenggenommen ja nicht (unabhängig davon, ob andere 
Metafunktionen das benutzen). Hier war m.E. schon die Absicht, das 
adaptiv gestalten zu können, indem bspw. size_type bei statischen 
Containern abhängig von der Größe deklariert wird. Hat man aber - aus 
für mich nicht ganz schlüssigen Gründen - nicht gemacht.

Natürlich kann man auch eine Meta-Funktion etwa std:size_type_t<...> 
einführen, auch als customization-point, und die spezialisieren. 
Trotzdem wäre es anders m.E. besser.

von vn nn (Gast)


Lesenswert?

Wilhelm M. schrieb:
> M.E. ist die starre Festlegung von array<>::size() auf size_t ein
> design-flaw. Aber man kann auch anderer Meinung sein aus Gründen der
> Kongruenz zu sizeof(). Außerdem hätte man sich dann auch den nested
> typ-alias size_type sparen können, wenn Größenangeben immer size_t
> sind. Aus Rückwärtskompatibilitätsgründen wird daran aber (im Moment)
> nichts geändert. Derartige Ungereimtheiten findet man auch an anderen
> Stellen.

Vermutlich sind die historischen Gründe wie so oft in C oder C++ die 
ausschlaggebenden. Dinge die schon immer so waren, oder die man 
einheitlich mit anderen Dingen gestaltet hat, die wiederum immer schon 
so waren, sind dann meistens schwer zu ändern.
Hätten die einzelnen Container untereinander unterschiedliche 
Verhaltensweisen, würde sicher wieder wer jammern. Würde sich das 
Verhalten von Containern von sizeof() oder anderen Funktionen, die 
größen zurückgeben, unterscheiden, würde wahrscheinlich auch gejammert. 
Würde das Verhalten von std::array im nächsten Standard geändert, würde 
man sicher auch jammern.

Ein Grund zum jammern findet sich ja immer. Einerseits wird gejammert, 
dass C++ zu umfangreich wird und sich keiner mehr auskennt, andererseits 
wird gejammert, dass Spezialfälle wie dynamische Container mit 
statischer Maximalgröße nicht in der Standardlibrary enthalten sind.

von mh (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Hier war m.E. schon die Absicht, das
> adaptiv gestalten zu können, indem bspw. size_type bei statischen
> Containern abhängig von der Größe deklariert wird.

Ich vermute, dass sie erlauben wollten, dass std::vector und std::map 
unterschiedliche size_type haben können. Aktuell ist std::array der 
einzige Container, bei dem deine Idee nutzbar wäre(, wenn 
array::size_type nicht fix wäre)?

von Heiko L. (zer0)


Lesenswert?

vn nn schrieb:
> Dynamische Container machen bei so wenig RAM ohnehin keinen Sinn.

Globale statische Container stehen immer zu x% leer.
Ein einfacher Use-Case, von dem ich halbwegs überzeugt bin:
1
void INThandlerX() {
2
 queueSomeMessage();
3
}
4
5
main() {
6
 while(1) processMessageQueue();
7
}

Was soll die Obergrenze an Messages da sein? Eine artifizielle 
Beschränkung der maximal auflaufenden Nachrichten schadet nur der 
Allgemeinheit des Programentwurfs.

von Heiko L. (zer0)


Lesenswert?

vn nn schrieb:
> size_t oder so ein Verhalten ist ja auch keine Spezialität von C++, ist
> ja auch in C so, dass für Speichergrößen standardmäßig mal size_t
> verwendet wird, auch wenn in konkreten Anwendungen weniger reichen
> würde.

Ja, nee. Der Punkt ist genau, dass die C-Definition von size_t die von 
C++ in der Praxis ungünstig festlegt. Allerdings möchte ich mir DAS 
Chaos, wenn man mal in der STL std::size_t mit size_t inkompatibel 
definiert, lieber bei jemand anderem anschauen. Ist beides mal der Typ, 
den sizeof() zurückgibt. Das gibt bestimmt ein paar lustige 
Makro-Effekte. Je nach Front-End und dann mit Text-Ersetzung, mal dies 
mal jenes...
Und dann einfach mal Gentoo mit KDE durchbauen lassen.

vn nn schrieb:
> Ja klar ist std::list nicht Embedded-optimiert, aber gegenüber C, wo ich
> die komplette Implementierung per Hand erledigen muss, hab ich immer
> noch einen Vorteil.

vn nn schrieb:
> Man kann von der STL-Implementierung ja leicht eine eigene ableiten, und
> diese auf die eigenen Bedürfnisse zuschneiden, ohne sie komplett per
> Hand stricken zu müssen wie in C.

Ich fürchte, dass genau das eben nicht geht. Da müsste man schon den 
Code komplett duplizieren und - "leicht" würde die Anpassung eher nicht 
werden, wenn ich mir so einen typischen STL-Quelltext anschaue.
Andererseits ist so eine einfache "Buffer"-Klasse schnell eben 
hingeschrieben. "T*, malloc, free, begin(), end() - fertig?"

Wilhelm M. schrieb:
> Hat man aber - aus
> für mich nicht ganz schlüssigen Gründen - nicht gemacht.

Ich könnte mir vorstellen, dass zu viel Varianz in den std-Klassen wohl 
dazu führt, dass noch viel mehr als aktuell nur noch header-only 
implementiert werden kann. Es ist zwar suboptimal Container(-Referenzen) 
an Funktionen zu übergeben, aber so hat man wenigstens etwas, was nicht 
an 2000-Stellen jedesmal neu übersetzt werden muss und die 
Implementierung mit allen Details die Schnittstelle bildet.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Heiko L. schrieb:
> Globale statische Container stehen immer zu x% leer.

Bei µC sagt man gerne: für unbenutztes RAM bekommt man kein Geld zurück. 
Wenn Du verstehst was ich meine. Natürlich haben wir auch bei OS-support 
eine Obergrenze.

von Wilhelm M. (wimalopaan)


Lesenswert?

Heiko L. schrieb:
> Ich könnte mir vorstellen, dass zu viel Varianz in den std-Klassen wohl
> dazu führt, dass noch viel mehr als aktuell nur noch header-only
> implementiert werden kann.

Nein, das hat ja nichts miteinander zu tun. Außerdem hat header-only 
viele Vorteile.

>  Es ist zwar suboptimal Container(-Referenzen)
> an Funktionen zu übergeben,

Was meinst Du denn da mit? Was ist an pass-by-const-ref suboptimal?

> aber so hat man wenigstens etwas, was nicht
> an 2000-Stellen jedesmal neu übersetzt werden muss und die
> Implementierung mit allen Details die Schnittstelle bildet.

Da werden modules helfen.

von Heiko L. (zer0)


Lesenswert?

Wilhelm M. schrieb:
> Was ist an pass-by-const-ref suboptimal?

Man sollte Iteratoren übernehmen, um die Verwendung nicht 
einzuschränken.

Wilhelm M. schrieb:
> Da werden modules helfen.

Teilweise. Einfach nur eine shared lib im System austauschen geht mit 
templates halt konzeptionell nicht.
Aber wenn man sowieso immer alles neu baut, was man ausliefert, sollten 
die natürlich schon einiges bringen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Heiko L. schrieb:
> Man sollte Iteratoren übernehmen, um die Verwendung nicht
> einzuschränken.

Du schreibst wirr.

von Rolf M. (rmagnus)


Lesenswert?

Was soll daran wirr sein? Es ist gängige Praxis, auch bei den 
Standard-Algorithmen.

von Wilhelm M. (wimalopaan)


Lesenswert?

Wilhelm M. schrieb:
> Heiko L. schrieb:
>> Man sollte Iteratoren übernehmen, um die Verwendung nicht
>> einzuschränken.

Ich verstehe den Satz einfach nicht. Für mich ist das sinnfrei.
Vielleicht kannst Du es mir "übersetzen"?

von Rolf M. (rmagnus)


Lesenswert?

Man sollte aus Gründen der Flexibilität bevorzugen, seine Funktionen so 
zu schreiben, dass sie nicht eine Referenz auf den Container als 
Parameter wollen, sondern ein Iterator-Paar, eben so wie es die ganzen 
Standard-Algorithmen auch tun.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Man sollte aus Gründen der Flexibilität bevorzugen, seine Funktionen so
> zu schreiben, dass sie nicht eine Referenz auf den Container als
> Parameter wollen, sondern ein Iterator-Paar, eben so wie es die ganzen
> Standard-Algorithmen auch tun.

Das kann ich aus dem ursprünglichen Satz wirklich nicht entnehmen, es 
hat mit dem eigentlichen Problem rein gar nichts zu tun, und liegt in 
der Natur der Sache. Summa summarum: völlig sinnfrei.

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Summa summarum: völlig sinnfrei.

Na Moment mal, du hattest doch gefragt, warum man nicht Containter per 
Referenz an Funktionen übergeben soll:

Wilhelm M. schrieb:
>>  Es ist zwar suboptimal Container(-Referenzen)
>> an Funktionen zu übergeben,
>
> Was meinst Du denn da mit? Was ist an pass-by-const-ref suboptimal?

Das war die Antwort darauf, und jetzt beschwerst du dich dann, das das 
nichts mit dem Thema zu tun hat…

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Wilhelm M. schrieb:
>> Summa summarum: völlig sinnfrei.
>
> Na Moment mal, du hattest doch gefragt, warum man nicht Containter per
> Referenz an Funktionen übergeben soll:

Genau.


> Heiko L. schrieb:
>> Man sollte Iteratoren übernehmen, um die Verwendung nicht
>> einzuschränken.

Und das soll die Antwort sein? Der Satz ist doch vollkommen sinnfrei.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Das war die Antwort darauf, und jetzt beschwerst du dich dann, das das
> nichts mit dem Thema zu tun hat…

Ich beschwere mich gar nicht.
Ich pflege nur den hier üblichen Umgangston, sollte ich mich mal 
beschweren, dann hört sich das anders an.

von x^2 (Gast)


Lesenswert?

vn nn schrieb:
> Oh, tatsächlich. Hoppala, mein Fehler. Na immerhin ist scheinbar nicht
> nur "irgendein Depp bei Apple" dafür, um mal bei x^2's Wortlaut zu
> bleiben.

Ich habe "Hanswurst" gesagt, nicht "Depp". Bitte zitiere mich nicht auch 
noch falsch. Der Rest deiner Argumente besteht meist ebenfalls darin 
meine Aussagen absichtlich falsch zu replizieren und diesen Strohmann 
dann lustvoll zu bekämpfen. Mir ist sowas wirklich zu anstrengend und 
unseriös.


Ich möchte nur bzgl. Standard Wechsel noch etwas hier beitragen und 
würde mich dann ausklinken:

Es ist kein Automatismus, dass man Code z.B. für C++11 nicht mehr mit 
C++20 nutzen könnte oder umgekehrt. Ob das so ist, darüber entscheiden 
die Art der Änderungen, die zwischen den Standards existieren. 
Problematisch ist, wenn man Code gar nicht mehr so konstruieren KANN, 
dass er für beide Standards funktioniert.

Sobald ich ein C++20 Feature bewußt nutze, kann ich diesen Code 
natürlich nicht mehr direkt in C++11 nutzen. Darin besteht nicht das 
Problem: Man hat ein Problem wenn man Code schreiben MÖCHTE, der SOWOHL 
mit C++11 und C++20 verwendbar sein soll, und das geht nicht mehr mit 
vertretbarem Aufwand wegen der Art der Änderungen im neuen Standard.

Das durchbricht die Wiederverwendbarkeit des Codes in BEIDE Richtungen: 
Der neue Code funktioniert nicht mehr mit dem alten Standard, und der 
alte Code funktioniert nicht mehr mit dem neuem Standard.

(Wenn C++ diesen Weg einschlagen möchte, kann es sich dieses 
"Erfolgsrezept" ja bei Python abgucken, wo jedes Stückchen Code für eine 
spezifische Version geschrieben werden muss - von denen es unzählige 
gibt und die in vielen Details auch noch inkompatibel sind.)

Wir halten unseren Code absichtlich so, dass es keinen Unterschied 
macht, ob ein C89, C99 bis C17 Compiler am Werk ist. Dies erreichen wir, 
indem wir auf unbedeutende Features bewußt verzichten (die den Code aber 
an einen spezifischen Standard koppeln würden) und wichtige neue 
Features so kapseln, dass alte Standards alternative Implementierungen 
erhalten. Beispielsweise indem das Feature in einem Modul od Klasse 
gekapselt und dort per Präprozessor notwendige Unterscheidungen gemacht 
werden. Die Motivation ist, dass nicht für jedes Projekt immer der 
neuste Standard/Compiler verfügbar ist, man aber Code über möglichst 
viele Projekte wiederverwenden muss. Es gibt z.B. weitergepflegte 
Uralt-Projekte, deren IDE/Uralt-Compiler läuft nur noch in einer VM, da 
sie der Hersteller schon lange aufgegeben hat (und sogar auf neuen 
Windows Versionen gar nicht mehr lauffähig wäre). Aber auch diese 
Projekte möchten weitergepflegt und mit den aktuelle Versionen unserer 
Libraries versorgt werden.

von Wilhelm M. (wimalopaan)


Lesenswert?

x^2 schrieb:
> Wir halten unseren Code absichtlich so, dass es keinen Unterschied
> macht, ob ein C89, C99 bis C17 Compiler am Werk ist.

Das ist gut so und in Eurem Fall sicher notwendig.

Allerdings hat das nichts mit dem von Dir auch angeführten 
Anpassungsvorschlag zu tun, "volatile" in bestimmten Situation wie etwa 
compound-assignments in C++20 als deprecated zu kennzeichnen. Denn: 
schon jetzt ist jedes(!) Programm, was volatile benutzt, 
implementation-defined, also vom Compiler / Core abhängig.

Das sollte Dir bewusst sein. Du / Ihr müsst also sowieso entsprechende 
Vorkehrungen treffen, dort wo ihr volatile benutzt. Die in gcc-10 
eingebaute Warnung ist daher extrem hilfreich, die entsprechenden 
Stellen zu finden und - wie Du ja auch schreibst - entsprechend zu 
handeln. Diesmal aber nicht wegen der Sprachversion aka abstrakte 
Maschine, sondern wegen implementation-defined behaviour, was schon 
lange in Eurem Code schlummert. Es kommt also nur etwas hinzu, was ihr 
hättet eh berücksichtigen müssen.
Also: freut Euch auf gcc-10! (im übrigen ist ja volatile an sich 
deprecated (das wäre auch falsch) sondern nur bestimmte, fragwürdige, 
nicht vollständig spezifizierte Operationen damit).

von zitter_ned_aso (Gast)


Lesenswert?

Hallo,

noch mal eine ähnliche Frage:

Man kann ja mehrere Variablen in einer Zeile definieren
1
int x, y, z;

und es werden drei Variablen vom Typ "int" angelegt.

Warum kann man aber nicht genauso Variablen in einem Funktionskopf 
definieren?
1
void do_something (int x, y, z, int* p, int another_integer){
2
    
3
    //code
4
5
}

Ich verstehe schon, dass C das nicht unterstützt. Und darum geht das 
nicht.  Aber warum hat man das so nicht implementiert?

von Rolf M. (rmagnus)


Lesenswert?

zitter_ned_aso schrieb:
> Warum kann man aber nicht genauso Variablen in einem Funktionskopf
> definieren?
> void do_something (int x, y, z, int* p, int another_integer){
>
>     //code
>
> }
>
> Ich verstehe schon, dass C das nicht unterstützt. Und darum geht das
> nicht.  Aber warum hat man das so nicht implementiert?

Die ursprüngliche Syntax vor C89 war sowieso eine ganz andere 
(K&R-Stil). Da hat man die Typen dort gar nicht angegeben, sondern erst 
danach. Das sah etwa so aus:
1
void do_something(x, y, z, p, another_integer)
2
    int x, y, z;
3
    int* p;
4
    int another_integer;
5
{
6
}
Erst später kam man dann zu der heutigen Syntax, wo das nicht so geht. 
Das ist auch ganz gut so, denn in C++ macht man es quasi umgekehrt zu 
deiner Idee. Wenn nur ein Name für den Parameter angegeben ist statt 
zwei, dann ist das nicht der Name des Parameters, sondern seines Typs.
Ein
1
void do_something (int x, y, z)
bedeutet dort also, dass der erste Parameter vom Typ int ist und x 
heißt, der zweite vom Typ y und keinen Namen hat und der dritte vom Typ 
z und auch namenlos ist.

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

zitter_ned_aso schrieb:
> Warum kann man aber nicht genauso Variablen in einem Funktionskopf
> definieren?

Zum Glück kann man das nicht, sonst würden wir wahrscheinlich noch mehr 
von solchem "unglücklichen" Code sehen:
1
auto date = Date{1, 2, 3}; // mmh?

Die Parametertypen von mehrstellige Funktionen sollten sich immer 
unterscheiden und domänenspezifisch sein:
1
auto date1 = Date{Weekday{1}, Month{2}, Century{20}.year{3}};

Oder eben einstellige Funktionen:
1
auto date2 = Date{}.weekday(1).month(2).year(1903);

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.