Error flexible array member

My Struct looks like this: typedef struct storage { char ***data; int lost_index[]; int lost_index_size; int size; int allowed_memory_key_size; int allowed_memory_value_s...

My Struct looks like this:

typedef struct storage {
    char ***data;

    int lost_index[];
    int lost_index_size;

    int size;
    int allowed_memory_key_size;
    int allowed_memory_value_size;
    int memory_size;
    int allowed_memory_size; 

} STORAGE;

The error im getting is «error: flexible array member not at end of struct». Im aware that this error can be solved by moving int lost_index[] at the end of struct. Why should flexible array member need to be at the end of struct? What is reason?

As this is assumed duplicate of another question, actually i didn’t find answers that i actually needed, answers in similar question dont describe the reason which stands behind compiler to throw error i asked about.

Thanks

asked May 11, 2016 at 13:36

Strahinja Djurić's user avatar

5

Unlike array declarations in function parameters, array declared as part of a struct or a union must have a size specified (with one exception described below). That is why declaring

int lost_index[];
int lost_index_size;

is incorrect.

The exception to this rule is so-called «flexible array member», which is an array declared with no size at the end of the struct. You must place it at the end of the struct so that the memory for it could be allocated along with the struct itself. This is the only way the compiler could know the offsets of all data members.

If the compiler were to allow flexible arrays in the middle of a struct, the location of members starting with size, allowed_memory_key_size, and on, would be dependent on the amount of memory that you allocate to lost_index[] array. Moreover, the compiler would not be able to pad the struct where necessary to ensure proper memory access.

answered May 11, 2016 at 13:42

Sergey Kalinichenko's user avatar

0

No10

30 / 28 / 4

Регистрация: 03.06.2010

Сообщений: 465

1

25.07.2013, 12:27. Показов 4248. Ответов 5

Метки нет (Все метки)


Вот такой код:

C
1
2
3
4
5
typedef struct q_query {
    char query[]; //тут ошибка
    short past_time;
    short count;
} dQuery;

Ошибка вот такого содержания:

C
1
C:MyLangCdbmainvar.h|2|error: flexible array member not at end of struct|

Почему? В Чем проблема?

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Псевдослучайный

1946 / 1145 / 98

Регистрация: 13.09.2011

Сообщений: 3,215

25.07.2013, 14:19

2

А чего вы ожидали? Какого размера должен был получиться массив и, соответственно, по какому смещению компилятор должен разместить следующие поле?
Хотя если бы такое объявление было в конце структуры, то о размере query можно было бы позаботиться вручную при выделении памяти.



0



Модератор

Эксперт PythonЭксперт JavaЭксперт CЭксперт С++

11660 / 7173 / 1704

Регистрация: 25.07.2009

Сообщений: 13,144

25.07.2013, 14:45

3

Цитата
Сообщение от NoMasters
Посмотреть сообщение

Хотя если бы такое объявление было в конце структуры, то о размере query можно было бы позаботиться вручную при выделении памяти.

Какой-то подозрительный манёвр… А sizeof(struct q_query) что возвращать должен?



0



Модератор

Эксперт функциональных языков программированияЭксперт Python

33885 / 18911 / 3982

Регистрация: 12.02.2012

Сообщений: 31,716

Записей в блоге: 13

25.07.2013, 15:17

4

«flexible array member not at end of struct» — дословно означает, что динамический массив следует размещать последним элементом структуры.



0



NoMasters

Псевдослучайный

1946 / 1145 / 98

Регистрация: 13.09.2011

Сообщений: 3,215

25.07.2013, 16:00

5

Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

easybudda, размер без учёта динамического массива.

C
1
2
3
4
5
6
7
8
struct some
{
    int one;
    short arr[];
};
...
//если нужен массив из n элементов
struct some *ptr = malloc(sizeof(struct some) + n * sizeof(short));



1



easybudda

Модератор

Эксперт PythonЭксперт JavaЭксперт CЭксперт С++

11660 / 7173 / 1704

Регистрация: 25.07.2009

Сообщений: 13,144

25.07.2013, 16:36

6

Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

NoMasters, ну да, наверное, но конструкция всё равно опасная. Тогда нужно в самой структуре держать размер массива (ну это как бы само собой), главное по запарке не написать

C
1
2
3
struct some *ptr = malloc(sizeof(struct some) + n * sizeof(short));
//...
struct some wrong_copy = *ptr;

Самый надёжный, но кондовый и расточительный метод — держать в структуре массив максимально допустимого размера. Правда, если массив большой, а объектов структуры много — снова беда…



0



  • Home
  • Forum
  • General Programming Boards
  • C Programming
  • flexible array member not at end of struct

  1. 05-05-2004


    #1

    krappa is offline


    Lode Runner


    flexible array member not at end of struct

    in a struct, I would have an array of size [][3], where [] is undefined. But it won’t work :

    example

    Code:

    struct foo {
        int bar[][3];
    };

    I get :

    Code:

     11: error: flexible array member not at end of struct

    I can’t use cause then I have bar[3][].

    Anyone ?… Anyone ?


  2. 05-05-2004


    #2

    Hammer is offline


    End Of Line

    Hammer's Avatar


    The size of the array must be known at compile time. So, either go with a fixed array size:
    int foo[10][3];
    or go with an array of pointers and malloc the memory later on.

    When all else fails, read the instructions.
    If you’re posting code, use code tags: [code] /* insert code here */ [/code]


  3. 05-05-2004


    #3

    krappa is offline


    Lode Runner


    OK, so what would the malloc line look like ?

    Code:

    myFoo.bar=malloc(3*size*sizeof(int));

    or should I make two mallocs (one for *(myFoo.bar) and one for myFoo.bar) ? though I don’t know how to write the first one.

    pointers and memory management are still fuzzy to me


  4. 05-06-2004


    #4

    krappa is offline


    Lode Runner


    OK, I’m advancing here. I have my struct now like this

    Code:

    struct foo {
          int **bar;
          int **bar2;
    }

    and it works in most cases.

    the problem is I want to use a foo as a global variable. But I can’t if I don’t give the entries to the struct. and bar2 is not easy stuff. I have a big function to calculate bar2’s entries. I can’t just write them down.

    Any ideas on how to handle this ?


  5. 05-06-2004


    #5

    nonpuz is offline


    Ultraviolence Connoisseur


    You want to make a variable of type struct foo, global or foo itself? just declare it outside of any functions (and above them)


  6. 05-06-2004


    #6

    Hammer is offline


    End Of Line

    Hammer's Avatar


    When all else fails, read the instructions.
    If you’re posting code, use code tags: [code] /* insert code here */ [/code]


  7. 05-06-2004


    #7

    Salem is offline


    and the hat of int overfl

    Salem's Avatar


    Which compiler are you using?

    Code:

    struct foo {
        int a;
        int bar[][3];
    };

    compiles it just fine with
    gcc -std=c99 prog.c

    Bear in mind that it is wrong to have a struct consisting only of a flexible array
    Commenting out the int a; causes gcc to report
    flexible array member in otherwise empty struct


  8. 05-14-2004


    #8

    krappa is offline


    Lode Runner


    I toyed around for a while with what you guys told me, understood some important I am sillyI am sillyI am sillyI am silly, learned a few tricks, and finally, when I thought everything was going to work I have some new stupid problems.

    first of all :

    compiles it just fine with
    gcc -std=c99 prog.c

    doesn’t work, I get the same goddamn errors. I guess it the BSD kernel or something, security issues maybe.

    Next, i still have my struct but this time I’m trying to mallocate it.

    Code:

    struct foo {
          int **bar;
    }

    Everything compiles nicely with this, but when I try to declare a foo type global variable in the main program with this line :

    Code:

    struct foo *myFoo = malloc(12*sizeof(int));

    I get :

    Code:

    error: initializer element is not constant

    I put (12*sizeof(int)) thinking of bar being 4×3…


  9. 05-14-2004


    #9

    Kip Neuhart is offline


    Registered User


    >error: initializer element is not constant
    You can’t call malloc outside of a function. Global initializers must be constant.

    When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.


  10. 05-14-2004


    #10

    anonytmouse is offline


    Yes, my avatar is stolen

    anonytmouse's Avatar


    I think this is what you’re trying to do:

    Code:

    #include <stdlib.h>
    #include <stdio.h>
    
    struct foo
    {
    	int (* bar)[3]; /* Declares a pointer to an int array[3] */
    };
    
    struct foo myFoo;
    
    int main(void)
    {
    	int i, j;
    	int k = 0;
    
    	/* Allocate memory for myFoo.bar */
    	myFoo.bar = malloc(4 * sizeof(*myFoo.bar));
    
    	/* Check success of memory allocation */
    	if (myFoo.bar == NULL)
    	{
    		fprintf(stderr, "Out of memoryn");
    		return EXIT_FAILURE;
    	}
    
    	/* Sample usage of myFoo.bar */
    
    	for (i = 0;i < 4;i++)
    		for (j = 0;j < 3;j++)
    			myFoo.bar[i][j] = k++;
    
    	for (i = 0;i < 4;i++)
    		for (j = 0;j < 3;j++)
    			printf("myFoo.bar[%d][%d] = %dn", i, j, myFoo.bar[i][j]);
    
    
    	/* Use myFoo in the rest of your program as needed. */
    
    	getchar();
    	return EXIT_SUCCESS;
    }

    Note especially the method of declaring a pointer to an int array[3]. This is covered in more detail in «Chapter 8: Pointers to Arrays» at the site Hammer linked to.

    Last edited by anonytmouse; 05-14-2004 at 06:48 AM.


  11. 05-14-2004


    #11

    krappa is offline


    Lode Runner


    YES ! PERFECT ! THANK YOU !

    I guess you guys spent a whole lot of time coding in C

    I’ve got to get used to thinking like this.

    Well, thanks a lot everyone.


  12. 05-14-2004


    #12

    krappa is offline


    Lode Runner


    not so perfect,

    I can only fill the first row of bar. when I start putting some stuff in myFoo.bar[1][0], I get a Bus Error.

    Can anyone explain ?

    actually your code works but mine (the real one, not the example) doesn’t. I’ll check this a little further.

    Last edited by krappa; 05-14-2004 at 11:09 AM.


  13. 05-14-2004


    #13

    krappa is offline


    Lode Runner


    I’d changed the .c but not the .h

    Some days I really loathe myself.


  14. 05-14-2004


    #14

    Salem is offline


    and the hat of int overfl

    Salem's Avatar


    I dunno if this is what you’re trying to do — you keep changing between arrays and pointers.

    Code:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct foo {
        char name[20];  // 20
        int a;          // 4
        int bar[][3];   // 12*n
    };
    
    int main()
    {
        struct foo *jobber;
        size_t  alloc;
        int     i, j;
    
        printf( "%un", sizeof *jobber );
        printf( "%un", sizeof jobber->a );
        printf( "%un", sizeof jobber->bar[0] );
        
        // put a bar[10][3] at the end of the structure
        alloc = sizeof *jobber + sizeof jobber->bar[0] * 10;
        printf( "allocating %u bytesn", alloc );
    
        jobber = malloc( alloc );
        strcpy( jobber->name, "hello" );
        jobber->a = 123;
        for ( i = 0 ; i < 10 ; i++ ) {
            for ( j = 0 ; j < 3 ; j++ ) {
                jobber->bar[i][j] = i * j;
            }
        }
        return 0;
    }


Popular pages

  • Exactly how to get started with C++ (or C) today
  • C Tutorial
  • C++ Tutorial
  • 5 ways you can learn to program faster
  • The 5 Most Common Problems New Programmers Face
  • How to set up a compiler
  • 8 Common programming Mistakes
  • What is C++11?
  • Creating a game, from start to finish

Recent additions subscribe to a feed

  • How to create a shared library on Linux with GCC — December 30, 2011
  • Enum classes and nullptr in C++11 — November 27, 2011
  • Learn about The Hash Table — November 20, 2011
  • Rvalue References and Move Semantics in C++11 — November 13, 2011
  • C and C++ for Java Programmers — November 5, 2011
  • A Gentle Introduction to C++ IO Streams — October 10, 2011

Similar Threads

  1. Replies: 10

    Last Post: 10-09-2006, 10:36 AM

  2. Replies: 20

    Last Post: 06-27-2006, 12:13 AM

  3. Dikumud

    By maxorator in forum C++ Programming

    Replies: 1

    Last Post: 10-01-2005, 06:39 AM

  4. Replies: 3

    Last Post: 09-11-2005, 12:19 PM

  5. Replies: 6

    Last Post: 04-17-2005, 07:10 AM

Example

C99

Type Declaration

A structure with at least one member may additionally contain a single array member of unspecified length at the end of the structure. This is called a flexible array member:

struct ex1 
{
    size_t foo;
    int flex[];
};

struct ex2_header 
{
    int foo;
    char bar;
};

struct ex2 
{
    struct ex2_header hdr;
    int flex[];
};

/* Merged ex2_header and ex2 structures. */
struct ex3 
{
    int foo;
    char bar;
    int flex[];
};

Effects on Size and Padding

A flexible array member is treated as having no size when calculating the size of a structure, though padding between that member and the previous member of the structure may still exist:

/* Prints "8,8" on my machine, so there is no padding. */
printf("%zu,%zun", sizeof(size_t), sizeof(struct ex1));

/* Also prints "8,8" on my machine, so there is no padding in the ex2 structure itself. */
printf("%zu,%zun", sizeof(struct ex2_header), sizeof(struct ex2));

/* Prints "5,8" on my machine, so there are 3 bytes of padding. */
printf("%zu,%zun", sizeof(int) + sizeof(char), sizeof(struct ex3));

The flexible array member is considered to have an incomplete array type, so its size cannot be calculated using sizeof.

Usage

You can declare and initialize an object with a structure type containing a flexible array member, but you must not attempt to initialize the flexible array member since it is treated as if it does not exist. It is forbidden to try to do this, and compile errors will result.

Similarly, you should not attempt to assign a value to any element of a flexible array member when declaring a structure in this way since there may not be enough padding at the end of the structure to allow for any objects required by the flexible array member. The compiler will not necessarily prevent you from doing this, however, so this can lead to undefined behavior.

/* invalid: cannot initialize flexible array member */
struct ex1 e1 = {1, {2, 3}};
/* invalid: hdr={foo=1, bar=2} OK, but cannot initialize flexible array member */
struct ex2 e2 = {{1, 2}, {3}};
/* valid: initialize foo=1, bar=2 members */
struct ex3 e3 = {1, 2};

e1.flex[0] = 3; /* undefined behavior, in my case */
e3.flex[0] = 2; /* undefined behavior again */
e2.flex[0] = e3.flex[0]; /* undefined behavior */

You may instead choose to use malloc, calloc, or realloc to allocate the structure with extra storage and later free it, which allows you to use the flexible array member as you wish:

/* valid: allocate an object of structure type `ex1` along with an array of 2 ints */
struct ex1 *pe1 = malloc(sizeof(*pe1) + 2 * sizeof(pe1->flex[0]));

/* valid: allocate an object of structure type ex2 along with an array of 4 ints */
struct ex2 *pe2 = malloc(sizeof(struct ex2) + sizeof(int[4]));

/* valid: allocate 5 structure type ex3 objects along with an array of 3 ints per object */
struct ex3 *pe3 = malloc(5 * (sizeof(*pe3) + sizeof(int[3])));

pe1->flex[0] = 3; /* valid */
pe3[0]->flex[0] = pe1->flex[0]; /* valid */

C99

The ‘struct hack’

Flexible array members did not exist prior to C99 and are treated as errors. A common workaround is to declare an array of length 1, a technique called the ‘struct hack’:

struct ex1 
{
    size_t foo;
    int flex[1];
};

This will affect the size of the structure, however, unlike a true flexible array member:

/* Prints "8,4,16" on my machine, signifying that there are 4 bytes of padding. */
printf("%d,%d,%dn", (int)sizeof(size_t), (int)sizeof(int[1]), (int)sizeof(struct ex1));

To use the flex member as a flexible array member, you’d allocate it with malloc as shown above, except that sizeof(*pe1) (or the equivalent sizeof(struct ex1)) would be replaced with offsetof(struct ex1, flex) or the longer, type-agnostic expression sizeof(*pe1)-sizeof(pe1->flex). Alternatively, you might subtract 1 from the desired length of the «flexible» array since it’s already included in the structure size, assuming the desired length is greater than 0. The same logic may be applied to the other usage examples.

Compatibility

If compatibility with compilers that do not support flexible array members is desired, you may use a macro defined like FLEXMEMB_SIZE below:

#if __STDC_VERSION__ < 199901L
#define FLEXMEMB_SIZE 1
#else
#define FLEXMEMB_SIZE /* nothing */
#endif

struct ex1 
{
    size_t foo;
    int flex[FLEXMEMB_SIZE];
};

When allocating objects, you should use the offsetof(struct ex1, flex) form to refer to the structure size (excluding the flexible array member) since it is the only expression that will remain consistent between compilers that support flexible array members and compilers that do not:

struct ex1 *pe10 = malloc(offsetof(struct ex1, flex) + n * sizeof(pe10->flex[0]));

The alternative is to use the preprocessor to conditionally subtract 1 from the specified length. Due to the increased potential for inconsistency and general human error in this form, I moved the logic into a separate function:

struct ex1 *ex1_alloc(size_t n)
{
    struct ex1 tmp;
#if __STDC_VERSION__ < 199901L
    if (n != 0)
        n--;
#endif
    return malloc(sizeof(tmp) + n * sizeof(tmp.flex[0]));
}
...

/* allocate an ex1 object with "flex" array of length 3 */
struct ex1 *pe1 = ex1_alloc(3);

View previous topic :: View next topic  
Author Message
Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sat Apr 25, 2020 6:53 pm    Post subject: C++ — Error when compiling Reply with quote

Hello, today i work into fan game project. But when i try to compile to check all of my project error, i have this (for information, i use boost lib):

Code:
In file included from Main.cpp:19:

Data/Type/TypeData.hpp:22:25: error: flexible array member ‘TypeData::WeaknessesIDTable’ not at end of ‘class TypeData’

   22 |     unsigned char       WeaknessesIDTable[];

      |                         ^~~~~~~~~~~~~~~~~

My file:

Code:
#ifndef TYPEDATA_H

#define TYPEDATA_H

class TypeData

{

public:

    TypeData();

    TypeData(unsigned short int id,

             std::string        name,

             unsigned char      weaknessesIDTable[],

             unsigned char      resistancesIDTable[],

             unsigned char      immunitiesIDTable[]);

    void SetID();

    void SetName();

    void SetWeaknessesIDTable();

    void SetImmunitiesIDTable();

    ~TypeData();

   

private:

    unsigned short int  ID;

    std::string         Name;

    unsigned char       WeaknessesIDTable[];

    unsigned char       ResistancesIDTable[];

    unsigned char       ImmunitiesIDTable[];

   

    template<class Archive>

    void serialize(Archive &archive, const unsigned int version){}

};

#endif

BOOST_CLASS_VERSION(TypeData, 0)

Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Sat Apr 25, 2020 7:45 pm    Post subject: Reply with quote

You can’t define a class with non-static data members of incomplete type, like WeaknessesIDTable, ResistancesIDTable and ImmunitiesIDTable. They are all arrays of unknown bound, and therefore incomplete. There is an exception for what is called a «flexible array member» (of a struct, which is what the error mesage refers to), but that applies to the C language, not to standard C++.
Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sat Apr 25, 2020 8:07 pm    Post subject: Reply with quote

Okay… how can i avoid that ?
Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Sat Apr 25, 2020 8:32 pm    Post subject: Reply with quote

By giving them bounds, or not defining them with array type. It depends on how you intend to use those class members.
Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sat Apr 25, 2020 8:57 pm    Post subject: Reply with quote

No, i need to have this parameter without limit.

Not defining array type ? How ?

Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Sat Apr 25, 2020 9:16 pm    Post subject: Reply with quote

For example, making them of type std::string if you want character strings, or of a type instantiated from a container class template like e.g. std::vector<unsigned char> if you want a container object to hold elements that the program is going to add dynamically, etc.
Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sat Apr 25, 2020 10:12 pm    Post subject: Reply with quote

I have changed all of my classes, but this error come again:

Code:
In file included from Main.cpp:18:

Data/PokemonInformation/PokemonInformationData.hpp:86:37: error: flexible array member ‘PokemonInformationData::TypesIDTable’ not at end of ‘class PokemonInformationData’

   86 |     std::vector<unsigned char>      TypesIDTable[];

      |                                     ^~~~~~~~~~~~

In file included from Main.cpp:20:

Data/Type/TypeData.hpp:22:38: error: flexible array member ‘TypeData::WeaknessesIDTable’ not at end of ‘class TypeData’

   22 |     std::vector<unsigned char>       WeaknessesIDTable[];

      |                                      ^~~~~~~~~~~~~~~~~

Two HPP files:

Code:
#ifndef POKEMONINFORMATIONDATA_H

#define POKEMONINFORMATIONDATA_H

class PokemonInformationData

{

public:

    PokemonInformationData();

    PokemonInformationData(unsigned short int              id,

                           unsigned short int              regionalID,

                           unsigned short int              globalID,

                           std::string                     name,

                           std::string                     description,

                           unsigned char                   colorID,

                           unsigned char                   catchingRate,

                           bool                            asexual,

                           unsigned char                   femaleRate,

                           std::string                     category,

                           float                           height,

                           float                           weight,

                           unsigned char                   bodyShapeID,

                           unsigned char                   experienceGroupID,

                           unsigned char                   eggGroupID,

                           unsigned short int              hatchingStepsNumber,

                           std::vector<unsigned char>      typesIDTable[],

                           std::vector<unsigned short int> abilitiesIDTable[],

                           std::vector<unsigned short int> movesIDTable[],

                           std::vector<unsigned char>      evGivenNumber[6],

                           //Egg (bébé)

                           //Evolutions

                           //Mega Evolution

                           unsigned short int              hp,

                           unsigned short int              attack,

                           unsigned short int              defense,

                           unsigned short int              specialAttack,

                           unsigned short int              specialDefense,

                           unsigned short int              speed);

    void SetID(unsigned short int id);

    void SetRegionalID(unsigned short int regionalID);

    void SetGlobalID(unsigned short int globalID);

    void SetName(std::string name);

    void SetDescription(std::string description);

    void SetColorID(unsigned char colorID);

    void SetCatchingRate(unsigned char catchingRate);

    void SetAsexual(bool asexual);

    void SetFemaleRate(unsigned char femaleRate);

    void SetCategory(std::string category);

    void SetHeight(float height);

    void SetWeight(float weight);

    void SetBodyShapeID(unsigned char bodyShapeID);

    void SetExperienceGroupID(unsigned char experienceGroupID);

    void SetEggGroupID(unsigned char EggGroupID);

    void SetHatchingStepsNumber(unsigned short int hatchingStepsNumber);

    void SetTypesIDTable(std::vector<unsigned char> typesIDTable[]);

    void SetAbilitiesIDTable(std::vector<unsigned short int> abilitiesIDTable[]);

    void SetMovesIDTable(std::vector<unsigned short int> movesIDTable[]);

    void SetEVGivenNumber(std::vector<unsigned char> evGivenNumber[6]);

    //Moves

    //Egg

    //Evolutions

    //Mega Evolution

    void SetHP(unsigned short int hp);

    void SetAttack(unsigned short int attack);

    void SetDefense(unsigned short int defense);

    void SetSpecialAttack(unsigned short int specialAttack);

    void SetSpecialDefense(unsigned short int specialDefense);

    void SetSpeed(unsigned short int speed);

    ~PokemonInformationData();

private:

    unsigned short int              ID;

    unsigned short int              RegionalID;

    unsigned short int              GlobalID;

    std::string                     Name;

    std::string                     Description;

    unsigned char                   ColorID;

    unsigned char                   CatchingRate;

    bool                            Asexual;

    unsigned char                   FemaleRate;

    std::string                     Category;

    float                           Height;

    float                           Weight;

    unsigned char                   BodyShapeID;

    unsigned char                   ExperienceGroupID;

    unsigned char                   EggGroupID;

    unsigned short int              HatchingStepsNumber;

    std::vector<unsigned char>      TypesIDTable[];

    std::vector<unsigned short int> AbilitiesIDTable[];

    std::vector<unsigned short int> MovesIDTable[];

    std::vector<unsigned char>      EVGivenNumber[6];

    //Moves

    //Egg

    //Evolutions

    //Mega Evolution

    unsigned short int              HP;

    unsigned short int              Attack;

    unsigned short int              Defense;

    unsigned short int              SpecialAttack;

    unsigned short int              SpecialDefense;

    unsigned short int              Speed;

   

    template<class Archive>

    void serialize(Archive &archive, const unsigned int version){}

};

#endif

BOOST_CLASS_VERSION(PokemonInformationData, 0)


Code:
#ifndef TYPEDATA_H

#define TYPEDATA_H

class TypeData

{

public:

    TypeData();

    TypeData(unsigned short int              id,

             std::string                     name,

             std::vector<unsigned char>      weaknessesIDTable[],

             std::vector<unsigned char>      resistancesIDTable[],

             std::vector<unsigned char>      immunitiesIDTable[]);

    void SetID();

    void SetName();

    void SetWeaknessesIDTable();

    void SetImmunitiesIDTable();

    ~TypeData();

   

private:

    unsigned short int               ID;

    std::string                      Name;

    std::vector<unsigned char>       WeaknessesIDTable[];

    std::vector<unsigned char>       ResistancesIDTable[];

    std::vector<unsigned char>       ImmunitiesIDTable[];

   

    template<class Archive>

    void serialize(Archive &archive, const unsigned int version){}

};

#endif

BOOST_CLASS_VERSION(TypeData, 0)

Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Sat Apr 25, 2020 10:23 pm    Post subject: Reply with quote

You are making the same mistake again. If you add «[]» after a member’s name in its declarator, you give it array type. Those members do not have type «std::vector<unsigned char>», they have type «array of std::vector<unsigned char> of unknown bound». A instance of std::vector<> is already ‘array-like’, drop the square brackets.
Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sat Apr 25, 2020 11:25 pm    Post subject: Reply with quote

Oh yes, thanks :)
Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sun Apr 26, 2020 12:14 pm    Post subject: Reply with quote

Just one another question. I search way to declare module into public section of my class header. Is it possible ?

Look:

Code:
#ifndef GAMEDATA_H

#define GAMEDATA_H

class GameData

{

public:

    static namespace Default

    {

        const unsigned short int Number = 0;

        const std::string        Text = «???»;

       

        const int                MaxMoney = 9999999;

    }

private:

};

#endif

Need i to pass static argument ? And how can i do that, i don’t have success.

In some words, i would like to have Game class, but if i need to pass default value to uninitialised value, i would like to do: Game::Default::Number without initialisation of Game class.

Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Sun Apr 26, 2020 2:33 pm    Post subject: Reply with quote

Fulgurance wrote:
Just one another question. I search way to declare module into public section of my class header. Is it possible ?

I have no idea about what you mean by «module» in this context. Standard C++ does not have any language construct with that name (yet).

Fulgurance wrote:
Code:
class GameData

{

public:

    static namespace Default

    {

        const unsigned short int Number = 0;

        const std::string        Text = «???»;

       

        const int                MaxMoney = 9999999;

    }

private:

};

You can’t define a namespace in class scope, and you can’t use a storage class specifier like static in a namespace definition. I don’t understand what you want to do here.

Fulgurance wrote:
Need i to pass static argument ? And how can i do that, i don’t have success.

In some words, i would like to have Game class, but if i need to pass default value to uninitialised value, i would like to do: Game::Default::Number without initialisation of Game class.

I’m not sure I understand this correctly, but if you want to be able to initialize the Number member to something other that 0, you declare a suitable constructor:

Code:
class GameData

{

private:

        const unsigned short int        Number;

        const std::string               Text;

        const int                       Money;

public:

          GameData(const unsigned short int n = 0): Number(n), Text(«???»), Money(9999999) {}

        // Rest of the definition

};

// Somewhere else in the program

GameData g1; //g1.Number == 0

GameData g2(23); //g2.Number == 23

Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Sun Apr 26, 2020 2:55 pm    Post subject: Reply with quote

Yes sorry, would like to say namespace (because before i have programmingin past in ruby and ruby named this module)
Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Sun Apr 26, 2020 4:07 pm    Post subject: Reply with quote

C++ namespaces can only be defined in file scope, and they are just a way to implement a hierarchical naming scheme, reducing the name collision problem that e.g. C has with its flat namespace for ordinary identifiers. Nothing more. In particular, all namespace members are ‘public’. I dont’t know Ruby, so I don’t know if there’s anything similar to what a module is in that language.
Back to top

View user's profile Send private message

Fulgurance
Veteran
Veteran

Joined: 15 Feb 2017
Posts: 1043

PostPosted: Tue Apr 28, 2020 3:40 pm    Post subject: Reply with quote

Okay, thank you:)

Just last question. I have made class have many std::vector as argument. When i call constructor, is it possible to pass directly vector as argument ? Because when i compile my main test program, i have errors:

Code:
zohran@MSI-GS73VR-6RF ~/Documents/Programmation/Pokémon $ LC_ALL=C g++ -o Main Main.cpp

Main.cpp: In function ‘int main(int, char**)’:

Main.cpp:41:37: error: expected identifier before numeric constant

   41 |                                    [0,1],

      |                                     ^

Main.cpp:41:38: error: expected ‘]’ before ‘,’ token

   41 |                                    [0,1],

      |                                      ^

      |                                      ]

Main.cpp: In lambda function:

Main.cpp:41:38: error: expected ‘{‘ before ‘,’ token

Main.cpp: In function ‘int main(int, char**)’:

Main.cpp:41:40: error: expected ‘)’ before ‘]’ token

   41 |                                    [0,1],

      |                                        ^

      |                                        )

Main.cpp:35:35: note: to match this ‘(‘

   35 |     PokemonInformationData pokemon(1,1,1,

      |   


Code:
#include <iostream>

#include <string>

#include <boost/archive/text_iarchive.hpp>

#include <boost/archive/text_oarchive.hpp>

#include <boost/serialization/vector.hpp>

#include <SFML/Graphics.hpp>

#include <SFML/Audio.hpp>

#include <SFML/Window.hpp>

#include <SFML/System.hpp>

#include «Code/Data/Ability/AbilityData.hpp»

#include «Code/Data/BodyShape/BodyShapeData.hpp»

#include «Code/Data/Effect/EffectData.hpp»

#include «Code/Data/EggGroup/EggGroupData.hpp»

#include «Code/Data/EvolutionCondition/EvolutionConditionData.hpp»

#include «Code/Data/ExperienceGroup/ExperienceGroupData.hpp»

#include «Code/Data/Game/GameData.hpp»

#include «Code/Data/ItemCategory/ItemCategoryData.hpp»

#include «Code/Data/ItemInformation/ItemInformationData.hpp»

#include «Code/Data/Move/MoveData.hpp»

#include «Code/Data/MoveInformation/MoveInformationData.hpp»

#include «Code/Data/MoveLearningCondition/MoveLearningConditionData.hpp»

#include «Code/Data/Nature/NatureData.hpp»

#include «Code/Data/Player/PlayerData.hpp»

#include «Code/Data/Pokedex/PokedexData.hpp»

#include «Code/Data/Pokemon/PokemonData.hpp»

#include «Code/Data/PokemonInformation/PokemonInformationData.hpp»

#include «Code/Data/Trainer/TrainerData.hpp»

#include «Code/Data/Type/TypeData.hpp»

int main(int argc = 0, char *argv[] = nullptr)

{

    PokemonInformationData pokemon(1,1,1,

                                   «Bulbizarre»,

                                   «Il est vert»,

                                   0,255,false,50,

                                   «Graine»,

                                   1.0,25.0,0,0,0,255,

                                   [0,1],

                                   [0],

                                   [0],

                                   [0],

                                   [0,0,0,0,0,0],

                                   1,1,

                                   5,5,5,5,5,5);

   

    std::cout << «Fermeture du programme» << std::endl;

   

    /*std::string current_input;*/

   

    /*std::cout << «>» << std::flush;*/

   

    /*while (std::getline(std::cin, current_input))

    {*/

        /*if (current_input == «Peux-tu couper le programme?»)

        {

         break;   

        }

        std::cout << «Intéressant…» << std::endl;*/

    //}

   

    /*std::cout << «Sans problème !» << std::endl;

    std::cout << «Fermeture du programme» << std::endl;*/

}

Back to top

View user's profile Send private message

GDH-gentoo
Veteran
Veteran

Joined: 20 Jul 2019
Posts: 1050
Location: South America

PostPosted: Tue Apr 28, 2020 5:50 pm    Post subject: Reply with quote

Fulgurance wrote:
Just last question. I have made class have many std::vector as argument. When i call constructor, is it possible to pass directly vector as argument ?

[…]

Code:
int main(int argc = 0, char *argv[] = nullptr)

{

    PokemonInformationData pokemon(1,1,1,

                                   «Bulbizarre»,

                                   «Il est vert»,

                                   0,255,false,50,

                                   «Graine»,

                                   1.0,25.0,0,0,0,255,

                                   [0,1],

                                   [0],

                                   [0],

                                   [0],

                                   [0,0,0,0,0,0],

                                   1,1,

                                   5,5,5,5,5,5);   

    // …

}

A comma-separated list of numbers in square brackets is not a valid syntax. If you want to initialize a vector member with a list of elements, you can do something like this:

Code:
#include <initializer_list>

#include <iostream>

#include <vector>

class Example {

private:

   std::vector<int> v1;

   std::vector<int> v2;

public:

   Example(std::initializer_list<int> l1, std::initializer_list<int> l2): v1(l1), v2(l2) {}

   auto &first() {return v1;}

   auto &second() {return v2;}

};

int main() {

   Example e({1, 2, 3}, {4, 5, 6});

   using std::cout;

   cout << «Members of e: v1 == [ «;

   for (auto x: e.first()) cout << x << ‘ ‘;

   cout << «] v2 == [ «;

   for (auto x: e.second()) cout << x << ‘ ‘;

   cout << «]n»;

   return 0;

}

Executing the example results in:

Code:
Members of e: v1 == [ 1 2 3 ] v2 == [ 4 5 6 ]

Back to top

View user's profile Send private message

Display posts from previous:   

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Понравилась статья? Поделить с друзьями:

Читайте также:

  • Error code 29 game client encountered an application error
  • Error flashing zip при прошивке twrp
  • Error code 29 eac
  • Error cannot load transport file
  • Error flashing the nvram intelligent provisioning

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии