how does this work?

Started by
18 comments, last by original vesoljc 21 years, 4 months ago
this a header file from the SDL library:
  
/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
*/

#ifdef SAVE_RCSID
static char rcsid =
 "@(#) $Id: SDL_types.h,v 1.6 2002/03/06 11:23:01 slouken Exp $";
#endif

/* General data types used by the SDL library */

#ifndef _SDL_types_h
#define _SDL_types_h

/* The number of elements in a table */
#define SDL_TABLESIZE(table)	(sizeof(table)/sizeof(table[0]))

/* Basic data types */
typedef enum {
	SDL_FALSE = 0,
	SDL_TRUE  = 1
} SDL_bool;
typedef unsigned char	Uint8;
typedef signed char	Sint8;
typedef unsigned short	Uint16;
typedef signed short	Sint16;
typedef unsigned int	Uint32;
typedef signed int	Sint32;

/* Figure out how to support 64-bit datatypes */
#if !defined(__STRICT_ANSI__)
#if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_C)
#define SDL_HAS_64BIT_TYPE	long long
#elif defined(_MSC_VER) /* VC++ */
#define SDL_HAS_64BIT_TYPE	__int64
#endif
#endif /* !__STRICT_ANSI__ */

/* The 64-bit type isn''t available on EPOC/Symbian OS */
#ifdef __SYMBIAN32__
#undef SDL_HAS_64BIT_TYPE
#endif

/* The 64-bit datatype isn''t supported on all platforms */
#ifdef SDL_HAS_64BIT_TYPE
typedef unsigned SDL_HAS_64BIT_TYPE Uint64;
typedef SDL_HAS_64BIT_TYPE Sint64;
#else
/* This is really just a hack to prevent the compiler from complaining */
typedef struct {
	Uint32 hi;
	Uint32 lo;
} Uint64, Sint64;
#endif

/* Make sure the types really have the right sizes */
#define SDL_COMPILE_TIME_ASSERT(name, x)               \
       typedef int SDL_dummy_ ## name[(x) * 2 - 1]

SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);
SDL_COMPILE_TIME_ASSERT(sint8, sizeof(Sint8) == 1);
SDL_COMPILE_TIME_ASSERT(uint16, sizeof(Uint16) == 2);
SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2);
SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4);
SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4);
SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8);
SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);

#undef SDL_COMPILE_TIME_ASSERT

/* General keyboard/mouse state definitions */
enum { SDL_PRESSED = 0x01, SDL_RELEASED = 0x00 };

#endif
  
most of the things are clear to be, execpt SDL_COMPILE_TIME_ASSERT. Could somebody please enlighten me how this macro works? Abnormal behavior of abnormal brain makes me normal...
Abnormal behavior of abnormal brain makes me normal...
Advertisement
I believe that function checks to make sure that all its datatypes are of a certain size.

It's basically to make sure that everything will work exactly the same on all platforms, in the rare case that a given platform uses datatypes of odd sizes.

edit:
And if you're wondering what it is because it's an assertion, then an ASSERT is a macro that is sent an expression (in this case "sizeof(Uint64) == 8"), and if that expression is false it creates an ASSERTION ERROR, which usually ends the program. It's a debug thing. Macros allow you to send an expression as a variable.

http://roninmagus.hopto.org
acronymfinder.com - Find any acronym you need!

[edited by - Ronin Magus on December 6, 2002 10:53:11 AM]

[edited by - Ronin Magus on December 6, 2002 10:54:05 AM]
I don't know SDL but I'd say it checks (at compile time) that his assumptions (sp?) for the size of certain data types is correct. Otherwise, things could get messy if someone tried to compile the source in an environment where a (socalled) int32 is 16 or 64 bits long.

Edit: Multitasking not good for humans. Stupid errors very likely.

[edited by - BitMaster on December 6, 2002 10:51:29 AM]
yeah ,i get the part that this macro checks if specifed types have correct size, but how does the actuall macro work?

#define SDL_COMPILE_TIME_ASSERT(name, x) \ typedef int SDL_dummy_ ## name[(x) * 2 - 1]SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);

SDL_COMPILE_TIME_ASSERT(name, x) - macro name right?
\ - why this
typedef int SDL_dummy_ ## name[(x) * 2 - 1] - consufing part
SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1);

why "uint8" ?


Abnormal behavior of abnormal brain makes me normal...
Abnormal behavior of abnormal brain makes me normal...
quote:Original post by original vesoljc
yeah ,i get the part that this macro checks if specifed types have correct size, but how does the actuall macro work?

It tries to create an array with a unique name based on the first parameter passed in. If the second expression passed in (e.g. sizeof(Uint8)) evaluates to false, it is converted to zero, and the computation produces an array size of -1, which is illegal. Compile error!

Example:
SDL_COMPILE_TIME_ASSERT(uint8, sizeof(Uint8) == 1); 

which the precompiler expands with this:
typedef int SDL_dummy_ ## name[(x) * 2 - 1] 

Pretend the result of the expression "sizeof(Uint8) == 1" is false, then plug in the values:
typedef int SDL_dummy_uint8name[(sizeof(Uint8) == 1) * 2 - 1] 

becomes:
typedef int SDL_dummy_uint8name[0 * 2 - 1] 


[edited by - SabreMan on December 6, 2002 11:05:15 AM]
cute...
and what''s with a "\"

Abnormal behavior of abnormal brain makes me normal...
Abnormal behavior of abnormal brain makes me normal...
quote:Original post by original vesoljc
cute...
and what''s with a "\"

Abnormal behavior of abnormal brain makes me normal...


"\" makes the compiller see two lines as being one. For example if you put one at the end of a line with a // comment, the comment will carry on to the next line.
even cooler...
one more...
what does ## operator do ?

Abnormal behavior of abnormal brain makes me normal...
Abnormal behavior of abnormal brain makes me normal...
## is a preprocessor operator which concatenates things, removing whitespace

#define zoom pr ## i ## ntf
zoom("Hello, world!\n");

Don''t listen to me. I''ve had too much coffee.
got it
is there any more general way to generate an error in preprocessor? instead of trying to an array with negative size ?

Abnormal behavior of abnormal brain makes me normal...
Abnormal behavior of abnormal brain makes me normal...

This topic is closed to new replies.

Advertisement