Toon posts:

[c++] #if expressies met sizeof(..) ??

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb iets vreemds met een #if expressie. Als ik zoiets als dit doe:
code:
1
2
3
#if (8>4)
..bla bla..
#endif
dan mag dat.

Als ik echter op die #if regel iets met sizeof(..) gebruik, wat volgens mij toch ook op compile time al vast staat, mag het niet:
code:
1
#if (sizeof(int)>4)
Hier krijg ik een error (invalid integer constant expression). Wat is dat voor onzin??
Overigens: ik gebruik ms vc++ 6, sp5.

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:00
Dit is geen onzin...
sizeof(int) is geen constante, terwijl 8 en 4 dat wel zijn.

Het resultaat van een sizeof staat imho niet vast at compile-time want dat kan volgens mij van platform tot platform verschillen.

https://fgheysels.github.io/


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 12:21
#if (en alle andere regels die met # beginnen) is een preprocessor directive. Deze worden verwerkt door de C preprocessor; een apart applicatie die VOOR de compiler wordt gedraait. Eigenlijk snapt deze preprocesser helemaal geen C; hij wordt bijvoorbeeld ook voor IDL gebruikt.

De preprocessor kan wel simpele expressies als (5*3>10) oplossen, maar hij kan geen gebruik maken van informatie die C/C++ compiler verzamelt, aangezien die nog helemaal niet actief is op het moment dat de preprocessor zijn werk doet. De preprocessor kan dus de waarde van sizeof() helemaal niet oplossen (is zich er ueberhaupt niet van bewust dat er C/C++ code wordt verwerkt) en dus kun je 'm ook niet in een expressie gebruiken die door de preprocessor opgelost moet worden.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 12:21
whoami schreef op 09 augustus 2002 @ 11:06:
Dit is geen onzin...
sizeof(int) is geen constante, terwijl 8 en 4 dat wel zijn.

Het resultaat van een sizeof staat imho niet vast at compile-time want dat kan volgens mij van platform tot platform verschillen.
Het spijt me, maar dat klopt niet. De compiler moet weten hoe groot variabelen zijn om zinnige code te kunnen generen, dus is het resultaat van een sizeof operator bij het compileren bekend. Hoe zou de compiler anders code kunnen genereren om argumenten op de stack te zetten of van de stack te halen?

Verwijderd

Topicstarter
Het resultaat van een sizeof staat imho niet vast at compile-time want dat kan volgens mij van platform tot platform verschillen.
Dan staat het toch wel vast, ik kan toch niet ff gauw van platform wisselen tussen het preprocessen en het compilen.
De preprocessor kan dus de waarde van sizeof() helemaal niet oplossen (is zich er ueberhaupt niet van bewust dat er C/C++ code wordt verwerkt
Ach fuck ja, natuurlijk... nouja, shit dan :/

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:00
Soultaker schreef op 09 augustus 2002 @ 11:11:
[...]

Het spijt me, maar dat klopt niet. De compiler moet weten hoe groot variabelen zijn om zinnige code te kunnen generen, dus is het resultaat van een sizeof operator bij het compileren bekend. Hoe zou de compiler anders code kunnen genereren om argumenten op de stack te zetten of van de stack te halen?


Idd, jullie hebben helemaal gelijk. Ik was het dan ook niet zeker (vandaar die 'imho').

https://fgheysels.github.io/


  • rollebol
  • Registratie: Mei 2000
  • Laatst online: 09-06 12:38
Natuurlijk is het waar dat de preprocessor niets weet van hoe groot een int is, maar er speelt nog iets anders een rol. 'sizeof' is eigenlijk een operator (wel een rare) waar je door middel van operator overloading een functie aan kan toekennen. Dit om user-gedefinieerde types te kunnen maken.

Als ik een preprocessor was die daar rekening mee moest houden zou ik gillend gek worden. :)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

sizeof() is bekend bij compile time, dat is een andere fase dan preprocessing.

  • XTerm
  • Registratie: Juli 2001
  • Laatst online: 10-06-2025
In <sys/types.h> zijn er typedefs om dit op te lossen, dan kan je dingen als int32 x; zeggen en dat weet je dat op *elk* platform x 4 byte groot gaat zijn.

Ik heb het echter nooit gebruikt (* XTerm is geen portability guy:)), dus je zal wat moeten rondneuzen in de headers.

Verwijderd

Topicstarter
dan kan je dingen als int32 x; zeggen en dat weet je dat op *elk* platform x 4 byte groot gaat zijn
Jep, ik ken ze. Thanks voor je hulp, maar.. eigenlijk ging het mij niet om sizeof(int) maar om sizeof(een of andere array) :)

Kep trouwens wel een oplossing voor m'n probleem:
code:
1
#define assert2(condition) typedef char __ASSERT2__[(condition)?1:-1]
Hiermee heb ik een soort compile-time assert. Als ik nu in m'n code "assert2(sizeof(int)==4)" neerzet, compiled het. Met iets anders dan 4 niet :)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

heb je hier nog iets aan?
////////////////////////////////////////////////////////////////////////////////
// The Loki Library
// Copyright (c) 2001 by Andrei Alexandrescu
// This code accompanies the book:
// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
// Patterns Applied". Copyright (c) 2001. Addison-Wesley.
// Permission to use, copy, modify, distribute and sell this software for any
// purpose is hereby granted without fee, provided that the above copyright
// notice appear in all copies and that both that copyright notice and this
// permission notice appear in supporting documentation.
// The author or Addison-Welsey Longman make no representations about the
// suitability of this software for any purpose. It is provided "as is"
// without express or implied warranty.
////////////////////////////////////////////////////////////////////////////////

// Last update: June 20, 2001

#ifndef STATIC_CHECK_INC_
#define STATIC_CHECK_INC_

namespace Loki
{
////////////////////////////////////////////////////////////////////////////////
// Helper structure for the STATIC_CHECK macro
////////////////////////////////////////////////////////////////////////////////

template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
}

////////////////////////////////////////////////////////////////////////////////
// macro STATIC_CHECK
// Invocation: STATIC_CHECK(expr, id)
// where:
// expr is a compile-time integral or pointer expression
// id is a C++ identifier that does not need to be defined
// If expr is zero, id will appear in a compile-time error message.
////////////////////////////////////////////////////////////////////////////////

#define STATIC_CHECK(expr, msg) \
{ Loki::CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }


////////////////////////////////////////////////////////////////////////////////
// Change log:
// March 20, 2001: add extra parens to STATIC_CHECK - it looked like a fun
// definition
// June 20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
////////////////////////////////////////////////////////////////////////////////

#endif // STATIC_CHECK_INC_

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
rollebol schreef op 09 augustus 2002 @ 11:24:
Natuurlijk is het waar dat de preprocessor niets weet van hoe groot een int is, maar er speelt nog iets anders een rol. 'sizeof' is eigenlijk een operator (wel een rare) waar je door middel van operator overloading een functie aan kan toekennen. Dit om user-gedefinieerde types te kunnen maken.

Als ik een preprocessor was die daar rekening mee moest houden zou ik gillend gek worden. :)
Als ik een compiler was overigens ook :) . Ook van een user-defined type kan de compiler het gewoon uitrekenen, is sizeof(members)+padding. En aangezien jij niet weet wat die padding is, kun je het niet eens uitrekenen, zelfs als je het zou overloaden. Sizeof overloaden kan daarom dus niet.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Onder unix is het gebruikelijk dat je de size van integers enzo (als je die wilt gebruiken) tijdens ./xonfigure bekijkt, en dat je daar dan een compile macro van maakt. Deze compiler macros kun je wel in #if constructies gebruiken. Voorbeeldje:

./configure.in/.ac:
code:
1
2
3
4
5
6
AC_CHECK_SIZEOF(int)
AC_DEFINE(SIZE_OF_INT, $ac_cv_sizeof_int)
AC_CHECK_SIZEOF(long)
AC_DEFINE(SIZE_OF_LONG, $ac_cv_sizeof_long)
AC_CHECK_SIZEOF(long long)
AC_DEFINE(SIZE_OF_LONG_LONG, $ac_cv_sizeof_long_long)


En dan een random .c of .h file:
code:
1
2
3
#if SIZE_OF_INT > 4
...
#endif


Dan moet je dus wel de GNU (of compatible) autoconf gebruiken voor configure.ac/.in. :).

edit:

is het trouwens niet zo dat een int onder windows altijd 32bits (4 byte) is? Zelfs onder die nieuwe nog-niet-bestaande 64bits windows of windowsNT4alpha?

Verwijderd

MSalters schreef op 09 augustus 2002 @ 14:36:
[...]
Ook van een user-defined type kan de compiler het gewoon uitrekenen, is sizeof(members)+padding. En aangezien jij niet weet wat die padding is, kun je het niet eens uitrekenen, zelfs als je het zou overloaden. Sizeof overloaden kan daarom dus niet.
Gelukkig, ik dacht al dat ik gek was. Ik gebruik namelijk gewoon sizeof van zelf gedefinieerde types, daar hoef ik helemaal geen overloading voor te gebruiken... Had het overigens nog nooit geprobeerd ook.
Blij dat er iemand is die hetzelfde denkt als ik. 8)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Overigens kan je sizeof() niet eens overloaden :)

edit:
oops sorry, msalters zei al hetzelfde

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 13:07

.oisyn

Moderator Devschuur®

Demotivational Speaker

Verwijderd schreef op 09 augustus 2002 @ 16:32:
Blij dat er iemand is die hetzelfde denkt als ik. 8)


denken en zeker weten zijn 2 hele verschillende dingen :Y)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1