Unsolved instance of a struct
-
Please, why have this error ?
dichiarative.cpp:11: undefined reference to `DichiarativeGlobali::paramingresso::arg_db_type' dichiarative.cpp:12: undefined reference to `DichiarativeGlobali::paramingresso::arg_db_driver' dichiarative.cpp:13: undefined reference to `DichiarativeGlobali::paramingresso::arg_db_name' dichiarative.cpp:14: undefined reference to `DichiarativeGlobali::paramingresso::arg_db_path'
File dichiarative .h
class DichiarativeGlobali { public: DichiarativeGlobali(); struct paramingresso { static QString arg_db_type; static QString arg_db_driver; static QString arg_db_name; static QString arg_db_path; }; paramingresso myParam; void setting_dichiarazioni(char* argomenti); };
file dichiarative.cpp
#include "dichiarative.h" DichiarativeGlobali::DichiarativeGlobali () { } void DichiarativeGlobali::setting_dichiarazioni(char* argomenti) { myParam.arg_db_type = QStringLiteral("%1").arg(argomenti[1]); myParam.arg_db_driver = QStringLiteral("%1").arg(argomenti[2]); myParam.arg_db_name = QStringLiteral("%1").arg(argomenti[3]); myParam.arg_db_path = QStringLiteral("%1").arg(argomenti[4]); }
[Edit aha_1980: Fixed typo in title]
-
@Digitale_GFacchini
Because of your use ofstatic
against each member? -
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 decoderQString::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 . . .
-
@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.
-
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 thestruct
, without correctly initializing these members. Inserting runtime code (inmain()
) to (try to) set their values will never resolve a compile-time issue. If you need clarification and are choosing to usestatic
insidestruct
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 usestatic
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. -
@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
indichiarative.h
file, so long as you include that in other files they can referenceDichiarativeGlobali::parametri_in_ingresso
to get thestruct
type (I don't know about yourtypedef
in C++).Meanwhile (and like I say I'm not sure what you're trying to achieve), your
main()
has a local variableDichiarativeGlobali dichiarative;
which it declares and uses. When you calldichiarative.setting_dichiarazioni(argv);
, that will call the function, which itself has its own, singlestatic 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 theDichiarativeGlobali::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 functionDichiarativeGlobali::mieiParametri DichiarativeGlobali::setting_dichiarazioni(char** argomenti)
, your problem will be that nobody other than the caller of that function will be able to access thatstatic struct
you just set up fromargv
. 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 indichiarative.h
and defined indichiarative.cpp
--- either singleton or static, which other modules then access. And thestatic DichiarativeGlobali::mieiParametri myParameter;
would then belong not inside a function likeDichiarativeGlobali::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.cppDichiarativeGlobali dichiarative; static DichiarativeGlobali::mieiParametri inputParameter = dichiarative.setting_dichiarazioni(argv);
But inputParameter.xxxx out main.cpp is blank.
-
@Digitale_GFacchini
I never said to just removestatic
insideDichiarativeGlobali::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[WHOOPS, SEE EDIT.]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++: thestruct
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).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 astruct
) to understand what I think you are wanting to achieve.P.S.
Try removing thestatic
at the start ofstatic 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... -
@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.
In this context
static
means a global variable irrespective of whether you put it inmain()
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/489865As 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!