Is there a standard way to check if struct member is uninitialized?
Maybe something like this?:
Code:if (STRUCT_OBJECT_NAME.member_name == null)
do_nothing();
Is there a standard way to check if struct member is uninitialized?
Maybe something like this?:
Code:if (STRUCT_OBJECT_NAME.member_name == null)
do_nothing();
Yes. Initialize said members. It sounds kind of paradoxical, but no one said that initialized variables had to be usable variables from the beginning. The point of initialization is so that a variable contains values you expect from the beginning.Quote:
Is there a standard way to check if struct member is uninitialized?
The problem is, I expect for the members to be initialized before doing anything with said members, but I want to guard against getting a struct object which has certain members unitialized accidentally, just in case. Note that I'm using a class object to deal with the struct object.
This is just to fool-proof my class.
You cannot initialize a struct without initializing all the members.Quote:
The problem is, I expect for the members to be initialized before doing anything with said members
If you missed a member, then the compiler will complain about too few initializers in an initializer list.Code:struct foo {
int a;
char *b;
float c;
}
bar = { 0, NULL, 0.0f };
So you either initialize, or you do not initialize.
ohh...
Not even with this syntax?:
I wasn't talking about initializer lists, btw, just to clarify what I meant by "initialize". I just meant give the members some content, i.e. since said members are vectors, I just wanted to check if they had objects added to them. But then I realized, all I had to do was check if said vector was empty. But I still would like to know if a standard method exists which allows you to check if a struct member (no matter what the type is) has been given content or not. But I guess not. Oh well...Code:
foo bar;
bar.a = 0;
bar.b = "A C-style string";
Because it was just meant to be a simple "S_html_attr" struct, which is operated on by my C_html4_attributes class. I did not want to tie the struct down to a specific set of supported html attributes. Instead, I define the set in C_html4_attributes, and use objects of S_html_attr as members of that class.
foo bar;
bar.a = 0;
bar.b = "A C-style string";
This is assignment, not initialization. Initialization is part of a declaration so either foo has a constructor which initializes all the members -- including by way of the annoying "default initialization" which is like no initialization, or you do it the C way.
There is no way to check this. Any value (like NULL for pointers) can be result of memory allocation. Just initialize them in the constructor.
Sorry, but we have no idea what your own structs do in your own code.Quote:
Because it was just meant to be a simple "S_html_attr" struct, which is operated on by my C_html4_attributes class. I did not want to tie the struct down to a specific set of supported html attributes. Instead, I define the set in C_html4_attributes, and use objects of S_html_attr as members of that class.
Really? What were you actually trying to achieve?
On your original question, there is no standard way to detect an uninitialised variable (be it a struct member or not). Even accessing the value of such a variable gives undefined behaviour (which means, since comparison involves retrieving the value, that comparing the value with anything does not work either).
I have a member function of my C_html4_attributes class, called "getAttr" which returns an S_html_attr. One of its parameters requires an attribute value to be passed. Inside the function, I check to see if the attribute value passed exists inside the supported attribute values vector container member of the struct "S_html_attr". I was wanting to not return anything if the supported attribute values member of the specified attribute had not been set yet. That is what prompted starting this thread.
But like already mentioned, I later realized I could always just check to see if the supported attribute values container member of the specified attribute was empty, by calling the empty() function of the vector. So that is what I'm actually doing. :p
Possibly. But he would have arrived at that conclusion himself if "not returning anything" meant avoiding a return instruction altogether.
To draw a parallel, searches do not throw exceptions for a failed search, but they also could be written to not return "anything" if anything means a usable iterator.
Experience has taught me that typically for anything failed, an exception is what is wanted, since you usually want to skip a body of code.
So I usually go by the rule: if something fails, throw an exception.
Otherwise add an "is there" function.
Yeah, that's the logic I was originally thinking in. By "not returning anything", I really meant not return anything useful, as in return a S_html_attr with none of its members assigned anything.
However, Elysia's suggestion sounds like a much better approach, so I think I'll use that instead.
Ok, I am going to throw an exception. However, how do I end the program from a function other than int main()?
What standard function can I call, that will work in any OS?
You are asking the wrong question. The question you should be asking is where do I handle the exception? The obvious answer to that is in main if you are simply going to terminate your program. Be sure to include detailed information about the error in the exception you throw.
Well, that may not be the best approach, I'm thinking, as I'm writing a set of classes for coding the Html language (I guess this would be called a library?), and I want to "package" everything together if I can. int main() will be in my actual program which uses this stuff, and I don't want to have to worry about specifics inside the set of classes, such as exceptions class functions throw (and then again, is an exception thrown inside of a class even visible inside int main()??). Also, I may want to write multiple programs using this library, and that's another reason why I don't want to concern myself with handling exceptions of class functions inside int main() functions.
Of course, if I'm thinking wrong again, feel free to correct me. :)
And you should be asking if it is an exception at all.
http://www.drdobbs.com/184401836
I wouldn't use exceptions for this problem because it doesn't sound like one exceptions will solve. You've described a failed search to me and there are ways to deal with that.
Actually, there's quite a bit of difference from a failed seach and a failed getAttr to me.
A failed search means said thing was not found, which is not an error because that is valid that that should happen: said object being searched in does not have to have the thing being searched for, otherwise there would be no reason to search now, would there? :)
A failed getAttr means that said attribute value did not exist in the specified attribute's supported attribute values.
Because you should only pass an attribute value which exists in attribute's supported attribute values, you failed to call the function properly, and therefore an exception is thrown. :p Of course, obviously, I don't HAVE to do it that way, but that would make it crystal clear to the caller that what he tried to pass was not supported. A proper call to C_html4_attributes::getAttr() should only occur after a S_html_attr_value is first created (and/or obtained by calling C_html4_attributes::getSupportedAttrValues() and then iterating through the vector<S_html_attr_value> returned) and its members assigned values that match the values of an S_html_attr_value supported by the attribute.
You knowing what to do is the important thing.
Like kmdv said, I am not aware of the significance of your own code. I wanted you to know whether this was really an exception or not, rather than using exceptions because Elysia said so.Quote:
Actually, there's quite a bit of difference from a failed seach and a failed getAttr to me.
I know that. I was just stating the reason why I decided to throw an exception (and it wasn't just because Elysia said to do it, it was because it seemed like a good idea, based on what my getAttr function is supposed to do).
Thanks for the help, everyone.
P.S. My above question about how to end the program from a function other than main() still stands.
EDIT: I guess exit() will work.
Technically you're supposed to use the STL with exceptions in mind. main() could look like this:
The moral: If you are writing a library, you need to provide documentation of your exceptions, so that people who use it (including yourself) will know what to catch. It is the user's responsibility to write this kind of code, not the supplier's.Code:try {
vector<string> elements;
elements.push_back(string("one"));
elements.push_back(string("two"));
elements.push_back(string("three"));
// code ...
}
catch (bad_alloc &loadError)
{
cerr << loadError.what() << endl;
return 0;
}
// other catches
// no-fail code here
return 0;
// verily, return 0 is guaranteed to work ;)
Ah, well exception's unwind the call stack.
So if you end up throwing an exception, from push_back() it might be caught where push_back() was used. If not there, then in the function that called that function, even if it was an object method. If not in the object method, then the object is destroyed when it has to go further into the call stack... until ultimately, main(). Now, either main() catches the exception or the program terminates badly with what's called an unhandled exception.
So writing exception safe classes is important for the users of your class: your class should always meet one of the guarantees elaborated on by the link I put. And you should make sure that you have a working destructor so that the call stack unwinding does not leak your object's memory.
Would it be considered bad coding style to throw and catch the object's own exceptions inside the object's member functions anyway? That way, int main() does not have to catch any exceptions (or at least, not from my library)?
How does it do that?Quote:
So writing exception safe classes is important for the users of your class: your class should always meet one of the guarantees elaborated on by the link I put. And you should make sure that you have a working destructor so that the call stack unwinding does not leak your object's memory.
And what would I need to destroy other than "new" objects of my class (which I don't have any of, at this time anyway) in my destructor?
I read the whole link you gave me (which, btw, confirmed to me that I should throw an exception for a failed getAttr), but it doesn't answer that question.
If you do that, you better rethrow it, else exceptions are no better than error codes. An exception the caller is not responsible for may as well not be an exception at all. And I know what you want.
It can depend on where you throw. For example, if you throw from a constructor, the destructors of data members will be called, but you could very easily leak memory from newed pointers. Usually you have to catch and rethrow the exception in order to clean up such things. And there are probably more places in your code than just the constructor with those circumstances, where you need to rethrow.
It's part of the exception feature. Since a function's call stack is going to be unwound, it is your responsibility to make sure all destructors are called, (i.e. that all memory is reclaimed) in order to not leak memory. Provide a working no-fail destructor.
Annoyingly, everything you need to know about exceptions will not be in one place. You basically have to know everything you can about exceptions (which is a textbook chapter topic) before you use them smartly. They are not a drag and drop feature.
If your library is going to be in a separate DLL file, make sure you don't throw an exception out of the DLL. Catch the exceptions in your public functions and convert them to standard error codes.
When creating any DLL, I'm trying to follow approach met in some libraries like DirectX:
Functions (with some exceptions like some getters) return an error code. If I want to return any value, struct, or interface, I simply pass it as a pointer. Exceptions contain error codes and are caught in the exported functions. When an exception is caught, its error code is returned.
You should not, unless it is something your library can handle.
If you need something cleaned up, make sure that that which needs cleaning up resides inside a class whose destructor will clean it up.
Exceptions should get propagated, so usually there is no need to catch them unless you need to handle them there and them.
And your library should not terminate your program, in any circumstances. It should propagate the error and your programer, the caller, the user, should handle them and gracefully exit if something goes wrong.
Isn't DLL a Windows library?
I was planning to make mine a cross-platform, if possible.
Also, my class functions all return const references, at this time, not pointers.
Well, I would say it say it is.
Yeah, I decided last night I'm not going to catch them inside my class functions. Instead, I'll just throw them, and leave them up to the user to catch. I also came to the conclusion that exiting from the program from my library was a really bad idea too.Quote:
If you need something cleaned up, make sure that that which needs cleaning up resides inside a class whose destructor will clean it up.
Exceptions should get propagated, so usually there is no need to catch them unless you need to handle them there and them.
And your library should not terminate your program, in any circumstances. It should propagate the error and your programer, the caller, the user, should handle them and gracefully exit if something goes wrong.
So I'm just going to throw all exceptions of C_html4_attributes to the user function to catch and deal with, the reason being that the user may want to retry calling one of the functions if he called it improperly the first time. So I can catch the exception(s) in the caller function, maybe inside of a loop, so that if an exception is thrown, I can just output its error, but keep going and keep retrying until the function is called correctly.
I'll do the same thing with the related classes C_html4_tags and C_html4_elements.
It does not matter whether it is DLL or shared object. If it is compiled with a different compiler or just different compiler version it must be separated. It also applies to static libraries.
You should not return references too. Return pointers and only to POD types.
References can be implemented in different ways.
Or just let the compiler compile the library. Throw in the source files / header files into the project and away you go.
It's really the only way to create modern, safe C++ code. DLL and other stuff are old technologies and the C++ standard is too vague on a lot of things to make such things possible.
I can't imagine a modern operating system without a possibility to produce code portable across languages and environments.
DLLs are simple and enable you to use your low level C code together with heavy and interpreted object-oriented scripts as well as with low level assembly procedural code. They were invited long time ago but they will also be present for a very long time. Knowing how to use C++ in a smart way can make writing external libraries much easier and much faster.
Anyway, I wouldn't throw sources into the project, I would create a static library instead.
DLLs are suited for C & co, but not C++. That's the whole point.