C vs C++ structuuruitlijning

Ik ben in een recent interview gevraagd naar de uitlijning van C++ struct-velden en heb getheoretiseerd dat C en C++ dezelfde strategie volgen bij structpacking.

Het was echter de verkeerde veronderstelling. De interviewer zei dat C en C++ over het algemeen structs op verschillende manieren inpakken en dat we nooit het tegenovergestelde mogen verwachten. IMHO het is een vreemde uitspraak. Er is geen pack "C"-kwalificatie voor structs in C++ voor gebruik in tweetalige C/C++-headerbestanden.

Dus in de praktijk kan het betekenen dat je geen struct in C++ kunt maken en deze aan een C-bibliotheek kunt doorgeven, omdat de velden over het algemeen op een andere manier worden uitgelijnd en verschillende offsets hebben. Maar in feite vertrouwen de meeste programmeurs serieus op deze interoperabiliteit tot het moment dat ze een aanwijzer converteren naar een C POD struct naar een verwijzing naar C++ wrapper rond deze struct met enkele hulpmethoden. Kunt u deze kwestie ophelderen?


Antwoord 1, autoriteit 100%

Zowel de C- als de C++-taalstandaarden stellen geen eisen aan structpadding en laten het over aan een implementatiedetail van de compiler. Een strikte interpretatie hiervan zou betekenen dat er geen garantie is dat een structuur tussen beide hetzelfde zou zijn.

In de praktijk kan een bepaalde versie van een toolchain die zowel C als C++ aankan (zoals GCC of Clang) een identieke struct op dezelfde manier verpakken, indien nodig. Zonder dit zou veel productiecode in de wereld gewoon niet werken. Dit is echter een garantie die wordt gegeven door de toolchain, en nietde taal.

Het is vermeldenswaard dat als u een soortgelijke struct als de C zou declareren, de originele toegangsspecificaties (private, publicen protected), dat de lay-out zou veranderen, maar dat is een beetje lang omdat de structuur niet langer identiek is.


Antwoord 2, autoriteit 42%

Dit was duidelijk verkeerd (van de kant van de interviewer). Het is duidelijk te zien dat structpacking hetzelfde is voor C en C++ voor iedereen die met een API-transactie op laag niveau heeft gewerkt met structs – bijvoorbeeld een netwerk-API. Dit zijn allemaal C-functies die ‘C’-structuren accepteren, maar toch veilig miljoenen miljoenen keren per dag worden aangeroepen vanuit C++-code.

Je moet geluk hebben dat je deze vraag had. Het maakt duidelijk dat je daar niet zou moeten werken.


Antwoord 3, autoriteit 6%

Toen C++ werd ontwikkeld, kwamen de ontwikkelaars erachter dat C-programmeurs vertrouwden op sommige dingen die de C++-ontwikkelaars niet wilden garanderen, maar als ze niet konden worden gegarandeerd, zou dat betekenen dat veel C-code die ook geldige C++-code was, zou zijn gebroken bij gebruik als C++-code. Niet wenselijk.

Daarom hebben ze “POD”-structuren uitgevonden: een structuur die geen C++-functies gebruikte, zou zich in een C++-programma precies hetzelfde gedragen als in een C-programma (afgezien van het feit dat door de implementatie gedefinieerd gedrag zou kunnen veranderen, aangezien een C-compiler en een C++-compiler zijn duidelijk niet dezelfde implementatie. Aan de andere kant zou de C++-compiler waarschijnlijk gewoon de implementatiedefinitie van de C-compiler kopiëren).

Als je een gewone C-struct neemt die ook een geldige C++-struct is (bijvoorbeeld geen leden met de naam “class”) en je voegt gewoon “public:” toe net na de openingsaccolade, dan is de lay-out, volgorde van leden, uitlijning enzovoort kunnen allemaal veranderen. Hoewel alle structleden standaard openbaar zijn, is er niets veranderd. Behalve dat vanwege het “publiek:” het geen POD meer is.

Other episodes