简体   繁体   中英

Variably modified, but err, how?

Ok, I understand this is probably ugly as heck, but I cannot understand why I cannot use TILES_X , TILES_Y or TILES_TOTAL as global array lengths, GCC crying about it being "Variably modified at file scope".

    /* How many points should be in each tile? */
    /* NOTE: MUST BE POWER OF TWO */
    #define TILE_WIDTH 32
    #define TILE_HEIGHT TILE_WIDTH
    #define TILE_AREA ( TILE_WIDTH * TILE_HEIGHT )

    /* How far should the origin of each tile be spaced? */
    #define TILE_OFFSET_X TILE_WIDTH
    #define TILE_OFFSET_Y ( TILE_HEIGHT * 0.866f )

    /* Relative to the origin, where does the tile really end? */
    #define TILE_MIN_X 0.0f
    #define TILE_MIN_Y 0.0f
    #define TILE_MAX_X ( TILE_OFFSET_X + 0.5f )
    #define TILE_MAX_Y ( TILE_OFFSET_Y + 0.5f )

    /* How many tiles should be cached offscreen? */
    #define TILE_BLEED 2

    #define CAMERA_WIDTH 256.0f
    #define CAMERA_HEIGHT 192.0f

    #define TILES_X ( ( size_t ) ( ( float ) ( ( CAMERA_WIDTH * 2.0f ) + ( TILE_BLEED * ( TILE_WIDTH + TILE_WIDTH ) ) ) / ( float ) TILE_OFFSET_X ) )
    #define TILES_Y ( ( size_t ) ( ( float ) ( ( CAMERA_HEIGHT * 2.0f ) + ( TILE_BLEED * ( TILE_HEIGHT + TILE_HEIGHT ) ) ) / ( float ) TILE_OFFSET_Y ) )
    #define TILES_TOTAL ( TILES_X * TILES_Y )

TILES_X expands to:
    ( ( size_t ) ( ( float ) ( ( 256.0f * 2.0f ) + ( 2 * ( 32 + 32 ) ) ) / ( float ) 32 ) )

Which should evaluate to a constant, right? I mean, there is nothing, NOTHING variable in there. If I try and define a variable with this an initializer it again cries about how it's variably modified. I don't see how. There are other posts about the same error, but it's always been solved using an enum or define instead of a const int.

Per 6.6, paragraph 6:

An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts . Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator.

(emphasis mine)

For the most part you cannot use floating point in an integer constant expression (which is required for array dimensions).

In any case, your use of floating point for this purpose is almost certainly wrong. Switch to using integer math and everything will work fine.

Edit: For example, instead of multiplying by 0.866f , you should multiply by 866 and then divide by 1000.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM