Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > de.comp.lang.c > #10619 > unrolled thread

[clang] Warnung bei unvollständiger Initialisierung von Struktur

Started byMichael Bäuerle <michael.baeuerle@stz-e.de>
First post2025-05-12 16:52 +0200
Last post2025-12-27 18:34 +0100
Articles 16 — 9 participants

Back to article view | Back to de.comp.lang.c


Contents

  [clang] Warnung bei unvollständiger Initialisierung von Struktur Michael Bäuerle <michael.baeuerle@stz-e.de> - 2025-05-12 16:52 +0200
    Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Stefan Reuther <stefan.news@arcor.de> - 2025-05-13 17:38 +0200
      Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Hermann Riemann <nospam.ng@hermann-riemann.de> - 2025-05-13 21:07 +0200
        Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Stefan Reuther <stefan.news@arcor.de> - 2025-05-14 18:12 +0200
          Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Marcel Mueller <news.5.maazl@spamgourmet.org> - 2025-05-14 19:30 +0200
            Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Rainer Weikusat <rweikusat@talktalk.net> - 2025-05-15 08:59 +0100
              Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Stefan Reuther <stefan.news@arcor.de> - 2025-05-15 18:44 +0200
                Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur "Peter J. Holzer" <hjp-usenet4@hjp.at> - 2025-05-15 20:17 +0200
                  Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Stefan Reuther <stefan.news@arcor.de> - 2025-05-16 18:08 +0200
                    Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Rainer Weikusat <rweikusat@talktalk.net> - 2025-05-18 19:14 +0100
                      Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Marcel Mueller <news.5.maazl@spamgourmet.org> - 2025-05-30 20:46 +0200
    Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Helmut Schellong <var@schellong.biz> - 2025-06-11 15:27 +0200
    Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Bastian Blank <usenet@waldi.eu.org> - 2025-06-15 19:26 +0000
      Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur "Peter J. Holzer" <hjp-usenet4@hjp.at> - 2025-06-15 21:58 +0200
        Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Michael Bäuerle <michael.baeuerle@stz-e.de> - 2025-06-16 10:33 +0200
    Re: [clang] Warnung bei unvollständiger Initialisierung von Struktur Bonita Montero <Bonita.Montero@gmail.com> - 2025-12-27 18:34 +0100

#10619 — [clang] Warnung bei unvollständiger Initialisierung von Struktur

FromMichael Bäuerle <michael.baeuerle@stz-e.de>
Date2025-05-12 16:52 +0200
Subject[clang] Warnung bei unvollständiger Initialisierung von Struktur
Message-ID<AABoIgsvoFsAAA3t.A3.flnews@WStation5.stz-e.de>
Testprogramm "initialize.c":
------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    struct
    {
        char *string;
        int   a;
        int   b;
    }
    my_struct = { NULL };

    printf("Value from struct: %d\n", my_struct.b);

    return EXIT_SUCCESS;
}
------------------------------------------------------------------------

$ clang --version
clang version 19.1.7
Target: x86_64-unknown-netbsd10.0
Thread model: posix
InstalledDir: /usr/pkg/bin

$ clang --std=c90 -Wextra -o initialize initialize.c 
initialize.c:12:24: warning: missing field 'a' initializer [-Wmissing-field-initializers]
   12 |     my_struct = { NULL };
      |                        ^
1 warning generated.

Wenn ich die Struktur so definiere, dass "string" zwischen "a" und "b"
liegt, dann gibt es keine Warnung (mit Initialisierung "{ 0 }").

Keines der Element ist ein "subaggregate" im Sinne der Norm.

In einem alten C draft von 1988 steht:
| 
|    If there are fewer initializers in a list than there are members of
| an aggregate, the remainder of the aggregate shall be initialized
| implicitly the same as objects that have static storage duration.

Im C23 draft N3220 steht das sinngemäß immer noch so drin (im Kapitel
6.7.11).

Ich hätte erwartet, dass die Reihenfolge hier keinen Einfluss hat
(also beidesmal die Warnung bzw. beidesmal keine Warnung).


PS: Mit GCC 12 gibt es diese Warnung nicht.

PPS: Es verhält sich nicht anders, wenn ich "--std=c23" bzw.
     "--std=c2x" angebe (wie erwartet).

[toc] | [next] | [standalone]


#10620

FromStefan Reuther <stefan.news@arcor.de>
Date2025-05-13 17:38 +0200
Message-ID<1000022.1co.1@stefan.msgid.phost.de>
In reply to#10619
Am 12.05.2025 um 16:52 schrieb Michael Bäuerle:
> Ich hätte erwartet, dass die Reihenfolge hier keinen Einfluss hat
> (also beidesmal die Warnung bzw. beidesmal keine Warnung).

Ich würde den Code ebenfalls für in Ordnung halten.

Es fällt auf, dass clang _keine_ Warnung mehr generiert, wenn man NULL
durch 0 ersetzt, obwohl der gleiche Maschinencode rauskommt. Das legt
nahe, dass die Compilerentwickler da einfach etwas übersehen haben.

Am Ende geht's ja bei Warnungen darum, legalen, aber möglicherweise
ungewollten Code zu melden, und um zu wissen, was ungewollt ist, muss
man eigentlich Hirne lesen, und die dazugehörigen Eingabegeräte sind
noch lange nicht serienreif. (Und der Entwickler bräuchte die
zuallererst, um das Hirn des Kunden zu lesen.)


  Stefan

[toc] | [prev] | [next] | [standalone]


#10621

FromHermann Riemann <nospam.ng@hermann-riemann.de>
Date2025-05-13 21:07 +0200
Message-ID<m8hjjrFd1goU1@mid.individual.net>
In reply to#10620
Am 13.05.25 um 17:38 schrieb Stefan Reuther:
> Am 12.05.2025 um 16:52 schrieb Michael Bäuerle:
>> Ich hätte erwartet, dass die Reihenfolge hier keinen Einfluss hat
>> (also beidesmal die Warnung bzw. beidesmal keine Warnung).
> 
> Ich würde den Code ebenfalls für in Ordnung halten.
> 
> Es fällt auf, dass clang _keine_ Warnung mehr generiert, wenn man NULL
> durch 0 ersetzt, obwohl der gleiche Maschinencode rauskommt. Das legt
> nahe, dass die Compilerentwickler da einfach etwas übersehen haben.

Ich initialisiere seit langen meine pointer ( insbesondere in struct )
mit memset(pointer,'\0',sizeof(etc

[toc] | [prev] | [next] | [standalone]


#10622

FromStefan Reuther <stefan.news@arcor.de>
Date2025-05-14 18:12 +0200
Message-ID<1002mel.19o.1@stefan.msgid.phost.de>
In reply to#10621
Am 13.05.2025 um 21:07 schrieb Hermann Riemann:
> Am 13.05.25 um 17:38 schrieb Stefan Reuther:
>> Am 12.05.2025 um 16:52 schrieb Michael Bäuerle:
>>> Ich hätte erwartet, dass die Reihenfolge hier keinen Einfluss hat
>>> (also beidesmal die Warnung bzw. beidesmal keine Warnung).
>>
>> Ich würde den Code ebenfalls für in Ordnung halten.
>>
>> Es fällt auf, dass clang _keine_ Warnung mehr generiert, wenn man NULL
>> durch 0 ersetzt, obwohl der gleiche Maschinencode rauskommt. Das legt
>> nahe, dass die Compilerentwickler da einfach etwas übersehen haben.
> 
> Ich initialisiere seit langen meine pointer ( insbesondere in struct )
> mit memset(pointer,'\0',sizeof(etc

Das ist im Gegensatz zu dem im OP genannten Code nicht zulässig, da ein
Nullpointer nicht nur aus Nullbits bestehen muss (auch wenn man die
Implementationen, auf die das zutrifft, vermutlich mit einer sehr großen
Lupe suchen muss).

Oder es ist ein Troll.


  Stefan

[toc] | [prev] | [next] | [standalone]


#10623

FromMarcel Mueller <news.5.maazl@spamgourmet.org>
Date2025-05-14 19:30 +0200
Message-ID<1002k0i$3q3f2$1@gwaiyur.mb-net.net>
In reply to#10622
Am 14.05.25 um 18:12 schrieb Stefan Reuther:
>> Ich initialisiere seit langen meine pointer ( insbesondere in struct )
>> mit memset(pointer,'\0',sizeof(etc
> 
> Das ist im Gegensatz zu dem im OP genannten Code nicht zulässig, da ein
> Nullpointer nicht nur aus Nullbits bestehen muss (auch wenn man die
> Implementationen, auf die das zutrifft, vermutlich mit einer sehr großen
> Lupe suchen muss).

inmos Transputer hatten als Basisadresse 0x80000000 (signed int)
0 war da eigentlich eine zulässige Adresse mitten im RAM, auch wenn 4GB 
damals durchaus unüblich waren. Bei den 16 Bit Modellen war es AFAIR 
aber analog.


Marcel

[toc] | [prev] | [next] | [standalone]


#10624

FromRainer Weikusat <rweikusat@talktalk.net>
Date2025-05-15 08:59 +0100
Message-ID<87plgapani.fsf@ftvaux.mobileactivedefense.com>
In reply to#10623
Marcel Mueller <news.5.maazl@spamgourmet.org> writes:
> Am 14.05.25 um 18:12 schrieb Stefan Reuther:
>>> Ich initialisiere seit langen meine pointer ( insbesondere in struct )
>>> mit memset(pointer,'\0',sizeof(etc
>> Das ist im Gegensatz zu dem im OP genannten Code nicht zulässig, da
>> ein
>> Nullpointer nicht nur aus Nullbits bestehen muss (auch wenn man die
>> Implementationen, auf die das zutrifft, vermutlich mit einer sehr großen
>> Lupe suchen muss).
>
> inmos Transputer hatten als Basisadresse 0x80000000 (signed int)
> 0 war da eigentlich eine zulässige Adresse mitten im RAM, auch wenn
> 4GB damals durchaus unüblich waren. Bei den 16 Bit Modellen war es
> AFAIR aber analog.

0 ist eigentlich immer eine zulässige Addresse. „Null pointer“ ist ein
abstraktes C-Konzept, das in dieser Allgemeinheit auf real existierender
Hardware meistens nicht existiert.

[toc] | [prev] | [next] | [standalone]


#10625

FromStefan Reuther <stefan.news@arcor.de>
Date2025-05-15 18:44 +0200
Message-ID<1005cmn.3h8.1@stefan.msgid.phost.de>
In reply to#10624
Am 15.05.2025 um 09:59 schrieb Rainer Weikusat:
> Marcel Mueller <news.5.maazl@spamgourmet.org> writes:
>> Am 14.05.25 um 18:12 schrieb Stefan Reuther:
>>> Nullpointer nicht nur aus Nullbits bestehen muss (auch wenn man die
>>> Implementationen, auf die das zutrifft, vermutlich mit einer sehr großen
>>> Lupe suchen muss).
>>
>> inmos Transputer hatten als Basisadresse 0x80000000 (signed int)
>> 0 war da eigentlich eine zulässige Adresse mitten im RAM, auch wenn
>> 4GB damals durchaus unüblich waren. Bei den 16 Bit Modellen war es
>> AFAIR aber analog.
> 
> 0 ist eigentlich immer eine zulässige Addresse. „Null pointer“ ist ein
> abstraktes C-Konzept, das in dieser Allgemeinheit auf real existierender
> Hardware meistens nicht existiert.

Im _segmentierten_ Protected Mode für i286/i386 ist "alles Nullbits" per
Hardwarespezifikation eine ungültige Adresse.

Allerdings gab's da auch das Gerücht, dass das so gemacht wurde, _weil_
C-Programme davon ausgehen, dass "alles Nullbits" eine ungültige Adresse
ist.


  Stefan

[toc] | [prev] | [next] | [standalone]


#10626

From"Peter J. Holzer" <hjp-usenet4@hjp.at>
Date2025-05-15 20:17 +0200
Message-ID<slrn102cbun.2oej.hjp-usenet4@trintignant.hjp.at>
In reply to#10625
On 2025-05-15 18:44, Stefan Reuther <stefan.news@arcor.de> wrote:
> Am 15.05.2025 um 09:59 schrieb Rainer Weikusat:
>> Marcel Mueller <news.5.maazl@spamgourmet.org> writes:
>>> Am 14.05.25 um 18:12 schrieb Stefan Reuther:
>>>> Nullpointer nicht nur aus Nullbits bestehen muss (auch wenn man die
>>>> Implementationen, auf die das zutrifft, vermutlich mit einer sehr großen
>>>> Lupe suchen muss).
>>>
>>> inmos Transputer hatten als Basisadresse 0x80000000 (signed int)
>>> 0 war da eigentlich eine zulässige Adresse mitten im RAM, auch wenn
>>> 4GB damals durchaus unüblich waren. Bei den 16 Bit Modellen war es
>>> AFAIR aber analog.
>> 
>> 0 ist eigentlich immer eine zulässige Addresse. „Null pointer“ ist ein
>> abstraktes C-Konzept, das in dieser Allgemeinheit auf real existierender
>> Hardware meistens nicht existiert.
>
> Im _segmentierten_ Protected Mode für i286/i386 ist "alles Nullbits" per
> Hardwarespezifikation eine ungültige Adresse.

So ist es. Und das (WIMRE) nicht nur beim Zugriff: Allein das Laden von
0000 in ein Segment-Register führt bereits zu einer Exception.
(Für C-Compiler dürfte das aber unproblematisch gewesen sein, weil die
für Pointer-Manipulationen (inkl. Vergleich mit NULL) schon aus
Performance-Gründen sicher normale Register verwendet haben.)


> Allerdings gab's da auch das Gerücht, dass das so gemacht wurde, _weil_
> C-Programme davon ausgehen, dass "alles Nullbits" eine ungültige Adresse
> ist.

Durchaus möglich. Der Zeitrahmen ist zwar etwas knapp (der 80286
erschien Anfang 1982 und da war C wohl noch nicht so dominant), aber
wenn Intel auf den Unix-Markt abzielte (wie ein Wikipedia-Autor
behauptet, was ein anderer mittels [citation needed] in Frage stellt),
dann wäre das eine naheliegende Entscheidung gewesen.

        hjp

[toc] | [prev] | [next] | [standalone]


#10627

FromStefan Reuther <stefan.news@arcor.de>
Date2025-05-16 18:08 +0200
Message-ID<1007uv8.404.1@stefan.msgid.phost.de>
In reply to#10626
Am 15.05.2025 um 20:17 schrieb Peter J. Holzer:
> On 2025-05-15 18:44, Stefan Reuther <stefan.news@arcor.de> wrote:
>> Am 15.05.2025 um 09:59 schrieb Rainer Weikusat:
>>> 0 ist eigentlich immer eine zulässige Addresse. „Null pointer“ ist ein
>>> abstraktes C-Konzept, das in dieser Allgemeinheit auf real existierender
>>> Hardware meistens nicht existiert.
>>
>> Im _segmentierten_ Protected Mode für i286/i386 ist "alles Nullbits" per
>> Hardwarespezifikation eine ungültige Adresse.
> 
> So ist es. Und das (WIMRE) nicht nur beim Zugriff: Allein das Laden von
> 0000 in ein Segment-Register führt bereits zu einer Exception.

Nullpointer darfst du laden, das gibt die Exception erst beim Zugriff.
Was du nicht darfst: einen Pointer laden, dessen Segmentregister keinem
von Null verschiedenen Segment entspricht.

Das erklärt die Regel, warum ein Pointer auf ein freigegebenes Objekt
ungültig wird ("The value of a pointer becomes indeterminate when the
object it points to reaches the end of its lifetime") - eine i286
Runtime könnte beim Freigeben des Objekts den Segmentdeskriptor
invalidieren, so dass bereits das Laden des Pointers eine Exception
generiert, nicht erst das Dereferenzieren.

> (Für C-Compiler dürfte das aber unproblematisch gewesen sein, weil die
> für Pointer-Manipulationen (inkl. Vergleich mit NULL) schon aus
> Performance-Gründen sicher normale Register verwendet haben.)

Die meisten, ja. Aber gerade in den Zeiten wie i286 modern und "ANSI C"
der neue heiße Scheiß war, hat man halt schon interessante ABIs
antizipiert. Nicht nur den langweiligen Standardkram mit 16-32
Registern, die alle gleich sind.


  Stefan

[toc] | [prev] | [next] | [standalone]


#10628

FromRainer Weikusat <rweikusat@talktalk.net>
Date2025-05-18 19:14 +0100
Message-ID<877c2drdlg.fsf@ftvaux.mobileactivedefense.com>
In reply to#10627
Stefan Reuther <stefan.news@arcor.de> writes:

[Grusel-Hardware aus den frühen 1980ern]

>> (Für C-Compiler dürfte das aber unproblematisch gewesen sein, weil die
>> für Pointer-Manipulationen (inkl. Vergleich mit NULL) schon aus
>> Performance-Gründen sicher normale Register verwendet haben.)
>
> Die meisten, ja. Aber gerade in den Zeiten wie i286 modern und "ANSI C"
> der neue heiße Scheiß war, hat man halt schon interessante ABIs
> antizipiert. Nicht nur den langweiligen Standardkram mit 16-32
> Registern, die alle gleich sind.

Man könnte auch sagen: Hatte man noch erheblich wirrere Vorstellungen
darüber, wie Hardware sich sinnvollerweise verhalten sollte, als das
heutzutage der Fall ist.

[toc] | [prev] | [next] | [standalone]


#10629

FromMarcel Mueller <news.5.maazl@spamgourmet.org>
Date2025-05-30 20:46 +0200
Message-ID<101cueo$2dfe$9@gwaiyur.mb-net.net>
In reply to#10628
Am 18.05.25 um 20:14 schrieb Rainer Weikusat:
> Stefan Reuther <stefan.news@arcor.de> writes:
> 
> [Grusel-Hardware aus den frühen 1980ern]
> 
>>> (Für C-Compiler dürfte das aber unproblematisch gewesen sein, weil die
>>> für Pointer-Manipulationen (inkl. Vergleich mit NULL) schon aus
>>> Performance-Gründen sicher normale Register verwendet haben.)
>>
>> Die meisten, ja. Aber gerade in den Zeiten wie i286 modern und "ANSI C"
>> der neue heiße Scheiß war, hat man halt schon interessante ABIs
>> antizipiert. Nicht nur den langweiligen Standardkram mit 16-32
>> Registern, die alle gleich sind.
> 
> Man könnte auch sagen: Hatte man noch erheblich wirrere Vorstellungen
> darüber, wie Hardware sich sinnvollerweise verhalten sollte, als das
> heutzutage der Fall ist.

+1

Unvergessen das Zitat (sinngemäß): "Mit OS/2 [1.3] hat IBM erfolgreich 
bewiesen, dass sich der 286-er nicht für Betriebssysteme eignet."


Marcel

[toc] | [prev] | [next] | [standalone]


#10630

FromHelmut Schellong <var@schellong.biz>
Date2025-06-11 15:27 +0200
Message-ID<102c08r$lmhu$1@solani.org>
In reply to#10619
Michael Bäuerle wrote on 12.05.2025 16:52:
> Testprogramm "initialize.c":
> ------------------------------------------------------------------------
> #include <stdio.h>
> #include <stdlib.h>
> 
> int main(void)
> {
>      struct
>      {
>          char *string;
>          int   a;
>          int   b;
>      }
>      my_struct = { NULL };
> 
>      printf("Value from struct: %d\n", my_struct.b);
> 
>      return EXIT_SUCCESS;
> }
> ------------------------------------------------------------------------
> 
> $ clang --version
> clang version 19.1.7
> Target: x86_64-unknown-netbsd10.0
> Thread model: posix
> InstalledDir: /usr/pkg/bin
> 
> $ clang --std=c90 -Wextra -o initialize initialize.c
> initialize.c:12:24: warning: missing field 'a' initializer [-Wmissing-field-initializers]
>     12 |     my_struct = { NULL };
>        |                        ^
> 1 warning generated.
> 
> Wenn ich die Struktur so definiere, dass "string" zwischen "a" und "b"
> liegt, dann gibt es keine Warnung (mit Initialisierung "{ 0 }").
> 
> Keines der Element ist ein "subaggregate" im Sinne der Norm.
> 
> [...]

Ich initialisiere sowieso pauschal stets vollständig - auf die eine oder andere Weise.
Damit vermeide ich jegliche (potentiellen) Probleme.
Eine 0 wird ja implizit passend gecastet.

Nicht selten lege ich (in einer Funktion) eine  static struct s_typ st0;  als init-Vehikel an.
Dies ist nur eine Variante von vielen möglichen.
Damit ergibt sich oft eine Verwendung von 16 Byte breiten Registern auf Assembler-Ebene - ultraschnell.
Neben Struktur-Zuweisungen verwende ich auch memset().


-- 
Mit freundlichen Grüßen
Helmut Schellong

[toc] | [prev] | [next] | [standalone]


#10631

FromBastian Blank <usenet@waldi.eu.org>
Date2025-06-15 19:26 +0000
Message-ID<slrn104u7ih.27ja3.usenet@mobilewave.waldi.eu.org>
In reply to#10619
Michael Bäuerle wrote:
>     struct
>     {
>         char *string;
>         int   a;
>         int   b;
>     }
>     my_struct = { NULL };

"NULL" ist kein valider Wert für a und b. Mach mal "0" draus, das ist
für alle Felder valid.

Bastian

[toc] | [prev] | [next] | [standalone]


#10632

From"Peter J. Holzer" <hjp-usenet4@hjp.at>
Date2025-06-15 21:58 +0200
Message-ID<slrn104u9fm.2r548.hjp-usenet4@trintignant.hjp.at>
In reply to#10631
On 2025-06-15 21:26, Bastian Blank <usenet@waldi.eu.org> wrote:
> Michael Bäuerle wrote:
>>     struct
>>     {
>>         char *string;
>>         int   a;
>>         int   b;
>>     }
>>     my_struct = { NULL };
>
> "NULL" ist kein valider Wert für a und b.

Ist auch nicht notwendig. NULL bezieht sich nur auf string.
Für a und b ist kein Wert angegeben, daher gilt für die default
initialization:

| If there are fewer initializers in a brace-enclosed list than there
| are elements or members of an aggregate[...]the remainder of the
| aggregate is subject to default initialization"

Und da gilt:

| — if it has arithmetic type, and it does not have decimal floating
|   type, it is initialized to (positive or unsigned) zero;

> Mach mal "0" draus, das ist für alle Felder valid.

Wenn ich mich recht erinnere, hat Michael ja schon festgestellt, dass
das hilft. Ist aber IMHO ein Compiler-Bug.

        hjp

[toc] | [prev] | [next] | [standalone]


#10633

FromMichael Bäuerle <michael.baeuerle@stz-e.de>
Date2025-06-16 10:33 +0200
Message-ID<AABoT9a+5LoAAAqQ.A3.flnews@WStation5.stz-e.de>
In reply to#10632
Peter J. Holzer wrote:
> On 2025-06-15 21:26, Bastian Blank <usenet@waldi.eu.org> wrote:
> > Michael Bäuerle wrote:
> > > 
> > >     struct
> > >     {
> > >         char *string;
> > >         int   a;
> > >         int   b;
> > >     }
> > >     my_struct = { NULL };
> > 
> > "NULL" ist kein valider Wert für a und b.
> 
> Ist auch nicht notwendig. NULL bezieht sich nur auf string.
> Für a und b ist kein Wert angegeben, daher gilt für die default
> initialization:
> 
> | If there are fewer initializers in a brace-enclosed list than there
> | are elements or members of an aggregate[...]the remainder of the
> | aggregate is subject to default initialization"
> 
> Und da gilt:
> 
> | — if it has arithmetic type, and it does not have decimal floating
> |   type, it is initialized to (positive or unsigned) zero;

Genau das wollte ich verwenden, also { NULL, 0, 0 } erhalten.

Seit C23 kann man auch empty initialization "{ }" verwenden, das
würde hier alle Elemente auf Standardwerte initialisieren.
Hier soll aber ausdrücklich kein C23 verwendet werden.

{ NULL } sollte konform zu allen genormten Versionen von C sein.

> > Mach mal "0" draus, das ist für alle Felder valid.
> 
> Wenn ich mich recht erinnere, hat Michael ja schon festgestellt, dass
> das hilft. Ist aber IMHO ein Compiler-Bug.

Nein, das war nicht das Problem. Ich hatte die Werte umsortiert,
d.h. die 0 hat einen Integer-Wert initialisiert:
| 
|     struct
|     {
|         int   a;
|         char *string;
|         int   b;
|     }
|     my_struct = { 0 };

Das erzeugte keine Warnung und müsste { 0, NULL, 0 } ergeben
(mit den Worten der Norm "null pointer constant" für den Zeiger).

[toc] | [prev] | [next] | [standalone]


#10634

FromBonita Montero <Bonita.Montero@gmail.com>
Date2025-12-27 18:34 +0100
Message-ID<10ip59h$3kim1$1@raubtier-asyl.eternal-september.org>
In reply to#10619
Ach Gott, diese Sprache ist einfach nur grauenhaft.
In C++ kann ich die selbe oder bessere Performance
haben und ich muss nicht jedes Bit einzeln rumdrehen.

Am 12.05.2025 um 16:52 schrieb Michael Bäuerle:
> Testprogramm "initialize.c":
> ------------------------------------------------------------------------
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(void)
> {
>      struct
>      {
>          char *string;
>          int   a;
>          int   b;
>      }
>      my_struct = { NULL };
>
>      printf("Value from struct: %d\n", my_struct.b);
>
>      return EXIT_SUCCESS;
> }
> ------------------------------------------------------------------------
>
> $ clang --version
> clang version 19.1.7
> Target: x86_64-unknown-netbsd10.0
> Thread model: posix
> InstalledDir: /usr/pkg/bin
>
> $ clang --std=c90 -Wextra -o initialize initialize.c
> initialize.c:12:24: warning: missing field 'a' initializer [-Wmissing-field-initializers]
>     12 |     my_struct = { NULL };
>        |                        ^
> 1 warning generated.
>
> Wenn ich die Struktur so definiere, dass "string" zwischen "a" und "b"
> liegt, dann gibt es keine Warnung (mit Initialisierung "{ 0 }").
>
> Keines der Element ist ein "subaggregate" im Sinne der Norm.
>
> In einem alten C draft von 1988 steht:
> |
> |    If there are fewer initializers in a list than there are members of
> | an aggregate, the remainder of the aggregate shall be initialized
> | implicitly the same as objects that have static storage duration.
>
> Im C23 draft N3220 steht das sinngemäß immer noch so drin (im Kapitel
> 6.7.11).
>
> Ich hätte erwartet, dass die Reihenfolge hier keinen Einfluss hat
> (also beidesmal die Warnung bzw. beidesmal keine Warnung).
>
>
> PS: Mit GCC 12 gibt es diese Warnung nicht.
>
> PPS: Es verhält sich nicht anders, wenn ich "--std=c23" bzw.
>       "--std=c2x" angebe (wie erwartet).

[toc] | [prev] | [standalone]


Back to top | Article view | de.comp.lang.c


csiph-web