instance of a struct



  • You are missing the definition of the static members. Make sure you are 100% certain you need them to be static, if that's the case then add the below to dichiarative.cpp

    QString DichiarativeGlobali::paramingresso::arg_db_type;
    QString DichiarativeGlobali::paramingresso::arg_db_driver;
    QString DichiarativeGlobali::paramingresso::arg_db_name;
    QString DichiarativeGlobali::paramingresso::arg_db_path;
    

    Also, QStringLiteral("%1").arg(argomenti[1]); is just doing the work twice, hiding the possible pitfall. replace it with an explicit call to the decoder QString::fromLatin1(argomenti[1]); (argv encoding is not standard, if you use non-ascii chars then you go in the land of dragons)



  • That's not the problem.
    Even if I create everything in the main (only as a test for gloabl variable). the result does not change.
    If you look at the code: I inserted a reading of the argv array. and the parameters are there.

    File main.cpp

    struct paramingresso {
        static QString arg_db_type;
        static QString arg_db_driver;
        static QString arg_db_name;
        static QString arg_db_path;
    };
    int main(int argc, char *argv[])
    {
    
    
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        int i = 1;
        printf("Ho ricevuto %d argomenti\n", argc-1);
        printf("Questi argomenti sono:\n");
         for(i=1; i<=argc-1; i++)
           printf("%s\n", argv[i]);
    
        paramingresso myParameter;
        myParameter.arg_db_type = argv[1];
        myParameter.arg_db_driver = argv[2];
        myParameter.arg_db_name = argv[3];
        myParameter.arg_db_path = argv[4];
    
    . . . .
    

    error is identic:

    main.cpp:55: undefined reference to `paramingresso::arg_db_type
    main.cpp:56: undefined reference to `paramingresso::arg_db_driver 
    main.cpp:57: undefined reference to `paramingresso::arg_db_name 
    main.cpp:58: undefined reference to `paramingresso::arg_db_path 
    . . . 
    

  • Qt Champions 2017

    @VRonin said in istance of a struct:

    You are missing the definition of the static members. Make sure you are 100% certain you need them to be static, if that's the case then add the below to dichiarative.cpp

    QString DichiarativeGlobali::paramingresso::arg_db_type;
    QString DichiarativeGlobali::paramingresso::arg_db_driver;
    QString DichiarativeGlobali::paramingresso::arg_db_name;
    QString DichiarativeGlobali::paramingresso::arg_db_path;
    

    Any cpp file will do, but you need it.


  • Lifetime Qt Champion

    Just a side note, you should consider using QCommandLineParser. Your current logic relies heavily on the fact that all arguments are provided.



  • @Digitale_GFacchini said in istance of a struct:

    That's not the problem.

    Two people have so far told you that the reason for your compile-time errors are your use of static in the struct, without correctly initializing these members. Inserting runtime code (in main()) to (try to) set their values will never resolve a compile-time issue. If you need clarification and are choosing to use static inside struct you might want to refer to how this works in C++.



  • @SGaist Good morning, you're right, but I'm following this as an exercise.
    However, I entered the following code to check and find no parameters.

        QCommandLineParser parser;
        const QStringList parametri_ingresso = parser.positionalArguments();
        for (int i = 0; i < parametri_ingresso.size(); ++i)
                std::cout << parametri_ingresso.at(i).toLocal8Bit().constData() << std::endl;
        return 0;
    

    This is response of the parser:

    parametri_ingresso.size()	0	int
    


  • @JonB hello, Yesterday evening I found that the probelma is the use of the static. In fact, removing the error does not occur.
    The reason for this exercise is: in some of its functions the program works differently according to the input variables. the parameters of argv.
    Without the static definition, the structure is set.

    How can these parameters set in this structure be read?

    Meanwhile, I'm going to study the use of static again.
    Thanks for now



  • @Digitale_GFacchini
    If you do wish to use static members in a C++ struct, for whatever reason, what others are telling you is that you will get that compilation error on, say, your line:

    myParameter.arg_db_type = ...
    ...
    

    until you change your code above that for paramingresso to read, say:

    struct paramingresso {
        static QString arg_db_type;
        static QString arg_db_driver;
        static QString arg_db_name;
        static QString arg_db_path;
    };
    
    QString DichiarativeGlobali::paramingresso::arg_db_type;
    QString DichiarativeGlobali::paramingresso::arg_db_driver;
    QString DichiarativeGlobali::paramingresso::arg_db_name;
    QString DichiarativeGlobali::paramingresso::arg_db_path;
    

    I'm not a C++-er(!), but if you try that you should find the compilation warning goes away?



  • @JonB if i use static that i have this error:

    undefined reference to `paramingresso::arg_db_type
    undefined reference to `paramingresso::arg_db_driver 
    undefined reference to `paramingresso::arg_db_name 
    undefined reference to `paramingresso::arg_db_path 
    


  • @Digitale_GFacchini
    You don't say which lines of code this is against.

    Like I said, I'm not a C++ expert. It may (well) be that you need those lines outside of any function/class in your main.cpp file. The principle of needing to declare them still remains the case. This applies to any C++ static class member variables. There are many Google resources covering the initialization needed; a random one I found is http://umich.edu/~eecs381/handouts/StaticMembers.pdf.


  • Qt Champions 2017

    @VRonin said it, I repeated, and I will reiterate yet again. Static members need definitions (look up the difference between a declaration and definition in C++). Without the definitions the compiler will not generate any symbols, and the linker will complain that it has no idea what any of these are, which is exactly what you get.

    "undefined reference" in linker-speak means: "dude, where's that stuff?!"



  • You are patient and kind. I understood the difference between definition and declaration and I executed the program correctly thanks to your clarifications.
    There is always only one thing.
    How can I declare and initialize a structure so that it is visible throughout the program? I thought it was fine static, but obviously I'm wrong.

    file dichiarative.h

    class DichiarativeGlobali
    {
    public:
         DichiarativeGlobali();
    
        typedef struct parametri_in_ingresso {
            QString arg_db_type;
            QString arg_db_driver;
            QString arg_db_name;
            QString arg_db_path;
        } mieiParametri
    
       DichiarativeGlobali::mieiParametri setting_dichiarazioni(char** argomenti);
    };
    

    dichiarative.cpp

    #include "dichiarative.h"
    
    DichiarativeGlobali::DichiarativeGlobali() { }
    
    DichiarativeGlobali::mieiParametri DichiarativeGlobali::setting_dichiarazioni(char** argomenti)
    {
        static DichiarativeGlobali::mieiParametri myParameter;
        myParameter.arg_db_type = argomenti[1];
        myParameter.arg_db_driver = argomenti[2];
        myParameter.arg_db_name = argomenti[3];
        myParameter.arg_db_path = argomenti[4];
    
        return myParameter;
    }
    

    fiale main.cpp

    int main(int argc, char *argv[]) {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
    
        DichiarativeGlobali  dichiarative;
        DichiarativeGlobali::mieiParametri inputParameter = dichiarative.setting_dichiarazioni(argv);
    . . . 
    
    }
    

    With debug in struct inputParameter i have correct value.
    Ok but i want use them in other function not only in main.cpp.
    If i put in definition struct in your memer "static" i have error "undefined reference".

    I hope I explained myself. thanks



  • @JonB thanks. I search with google since two days for this topic. I did not find an example with a struct with static members and invoked from other functions.



  • @Digitale_GFacchini
    I'm a bit lost at what you're asking/doing now.

    Declaring something static has nothing to so with its visibility, e.g. to other modules.

    Now that you have declared the struct in dichiarative.h file, so long as you include that in other files they can reference DichiarativeGlobali::parametri_in_ingresso to get the struct type (I don't know about your typedef in C++).

    Meanwhile (and like I say I'm not sure what you're trying to achieve), your main() has a local variable DichiarativeGlobali dichiarative; which it declares and uses. When you call dichiarative.setting_dichiarazioni(argv);, that will call the function, which itself has its own, single static DichiarativeGlobali::mieiParametri myParameter, which it returns to the caller as its result. So far as I can tell it will work. Because of the way you have written it, it should be OK for other lines of code to now access the DichiarativeGlobali::mieiParametri inputParameter you have decalred. But you'll have to pass that around as a parameter, and I'm not sure that's what you'll want to do....

    Because you declared the static DichiarativeGlobali::mieiParametri myParameter; inside the function DichiarativeGlobali::mieiParametri DichiarativeGlobali::setting_dichiarazioni(char** argomenti), your problem will be that nobody other than the caller of that function will be able to access that static struct you just set up from argv. I have a feeling that may not be what you want....

    At a guess, what you're probably looking for is to have a single, global DichiarativeGlobali dichiarativeGlobali; --- perhaps declared in dichiarative.h and defined in dichiarative.cpp --- either singleton or static, which other modules then access. And the static DichiarativeGlobali::mieiParametri myParameter; would then belong not inside a function like DichiarativeGlobali::setting_dichiarazioni but needs to be moved to top-level class scope.

    All of which is C++ and nothing to do with Qt, and is getting quite big. Perhaps a C++ expert will help you, I don't know....



  • @JonB said in istance of a struct:

    your problem will be that nobody other than the caller of that function will be able to access that

    all right. My declare inside the function it was a test. I have changed.
    I have removed static in the function.
    Then I put static when i declare it in main.cpp

        DichiarativeGlobali  dichiarative;
        static DichiarativeGlobali::mieiParametri inputParameter = dichiarative.setting_dichiarazioni(argv);
    

    But inputParameter.xxxx out main.cpp is blank.



  • @Digitale_GFacchini
    I never said to just remove static inside DichiarativeGlobali::setting_dichiarazioni in just that way. Assuming you now have:

    DichiarativeGlobali::mieiParametri DichiarativeGlobali::setting_dichiarazioni(char** argomenti)
    {
        DichiarativeGlobali::mieiParametri myParameter;
        myParameter.arg_db_type = argomenti[1];
        ...
    
        return myParameter;
    }
    

    then you now have created a local mieiParametri on the stack (not heap) and are then returning it to the outside world and try to access its members. You can't do that in C++: the struct will have been destroyed on exit from the function, to the best of my knowledge, and your member accesses will point to unknown data, which could give you any result (e.g. blank). [WHOOPS, SEE EDIT.]

    Whatever, this approach will not be correct.

    EDIT
    I'm more old-school. I checked and, say, https://stackoverflow.com/questions/9590827/is-it-safe-to-return-a-struct-in-c-or-c, does imply you can now do this return-struct-by-value thing, though it claims it varies by compiler, and/or implementation. All the more reason why I must step aside from a precise answer now...!

    I'm sorry, but this is a C++ question, and I don't claim to be a C++ expert. I will have to leave others to answer. But since it's not a Qt issue you might find answers elsewhere. Certainly you need to start reading about "global/static variables" and/or "singleton classes" (but not static members inside a struct) to understand what I think you are wanting to achieve.

    P.S.
    Try removing the static at the start of static DichiarativeGlobali::mieiParametri inputParameter = dichiarative.setting_dichiarazioni(argv);. static variable initializations happen very early, who knows...

    P.P.S.
    Even when you get this bit working, like I said I suspect your whole approach like now is not going to achieve what you want in the way of making these values available to every module, so you're going to have to do it a different way like I said anyway...


  • Qt Champions 2017

    @JonB said in istance of a struct:

    You can't do that in C++

    You can, I imagine you're thinking of references, which are glorified pointers, and there it may work, it may not depending on the context.

    does imply you can now do this return-struct-by-value thing,

    Not now, always has been this way. The only thin distinction is made between POD instances and the more complex kind which require a copy constructor to be handled properly.

    @Digitale_GFacchini

    In this context static means a global variable irrespective of whether you put it in main() or in the struct. Static members in structures require definitions (sigh), so for a structure declared like this:

    struct SomeStruct
    {
        static int member; //< This is a declaration
    };
    

    one needs a corresponding definition of the member somewhere in the global scope, like this:

    int SomeStruct::member; // This is a definition! (even though it doesn't set any value to the member)
    


  • @kshegunov
    Hello, my friend...

    does imply you can now do this return-struct-by-value thing,

    Not now, always has been this way. The only thin distinction is made between POD instances and the more complex kind which require a copy constructor to be handled properly.

    And you're going to show me copy-by-value-return-struct in K&R C, which I grew up with, right??

    EDIT
    Good grief!! https://stackoverflow.com/questions/9653072/return-a-struct-from-a-function-in-c says you're right!! My recollection is more like https://stackoverflow.com/a/9653951/489865

    As far as I can remember, the first versions of C only allowed to return a value that could fit into a processor register, which means that you could only return a pointer to a struct. The same restriction applied to function arguments.

    OK, I'll have to settle for "it was wicked" [old meaning of "wicked", not new one!]. Don't blame us if old C compiler blows up by not generating the right copying code in practice... :) Besides which, you never had enough memory to copy a C struct on the stack...

    Hmm, then again https://stackoverflow.com/a/12234227/489865 is the accepted answer:

    It's standard since C89. In K&R C, it was not possible to return structs, only pointers to structs.

    So maybe I am right about my recollection of K&R C!


  • Qt Champions 2017

    @JonB said in istance of a struct:

    says you're right

    Happens occasionally.

    Don't blame us if old C compiler blows up by not generating the right copying code in practice...

    I haven't seen such a compiler, although my programming experience is rather limited to be a measure for all the compilers old and new out there.

    So maybe I am right about my recollection of K&R C!

    I can't say. C89 was already around when I was a toddler ...



  • @kshegunov

    I haven't seen such a compiler

    I can't say. C89 was already around when I was a toddler ...

    There is a connection between those two statements (compared to my experience) :)



  • @JonB said in istance of a struct:

    Even when you get this bit working, like I said I suspect your whole approach like now is not going to achieve what you want in the way of making these values available to every module, so you're going to have to do it a different way like I said anyway...

    Good evening, I'm sorry for my absence.
    It's true! The problem is a C ++ concept that I have been studying for a short time, together with QT. But those who use QT, if I understand correctly, also know C ++. For that I asked the question here. Apart from that, I think it's right that what you said also on the approach. I think that my intent must act in another way. the question is which one?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.