Thread: Declare object without initializing

  1. #16
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    So am I suppose to keep all of main inside the try block then?
    At least all of the code in the global main function that uses valis, I suppose.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  2. #17
    Registered User
    Join Date
    Mar 2010
    Posts
    15
    Yes, laserlight is right. Use her code. Your mistake was double: You used the var valis outside of its scope AND you used it after it had failed to construct! It's all right, however, to have critical code in the constructor. After all, a net connection object is useless if the connection fails. Bubba's objection is not valid: You CAN have such an object as a member element too. It is constructed when the containing class C is, and if the member fails to construct so should C. You must catch an exception from trying to instantiate C.

  3. #18
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by MK27 View Post
    Okay, well the whole reason I started this thread was because the first (and so far, only) time I tried that I get an error:
    Code:
    int main() {
    	try {
    		OATserver valis(666, 1, "oatsv.log");
    	}
    	catch (int err) {
    		cerr << "OATserver FAIL -> ";
    		switch (err) {
    			case (SOCKERR):
    				perror("Socket: ");
    				break;
    			case (BINDERR):
    				perror("Bind: ");
    				break;
    			case (LISTENERR):
    				perror("Listen: ");
    				break;
    			default:
    				cerr << "??????\n";
    		}
    	}
    
    	struct sockaddr_in in;
    
    	valis.acptlist.push_back("127.0.0.1");
    	valis.waitOnCall(&in);
    
    	return 0;
    }
    server.cpp: In function ‘int main()’:
    server.cpp:92: error: ‘valis’ was not declared in this scope

    Is this some nuance here that will make this work? It seems very silly to me (altho it is normal scoping, wouldn't it be nice if try "returned" it's variables on sucess?), I am glad to hear it is not supposed to be that way.
    Like I said, how are you supposed to use valis if construction failed? This would invariably lead to a bug. The pointer solution has the same problem. You can only use valis if construction succeeds, so it is a good thing that the language won't let you use it when it might not have.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #19
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    MK27, it looks like you might be falling into the trap that some C to C++ learners fall into, in that they make lots of local exception catchers around just the one line that fails. This is the opposite of the ideal situation.
    What you need to do is to catch the exception as late or high up as possible.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  5. #20
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by King Mir View Post
    Like I said, how are you supposed to use valis if construction failed? This would invariably lead to a bug. The pointer solution has the same problem. You can only use valis if construction succeeds, so it is a good thing that the language won't let you use it when it might not have.
    Yes, that was the complete program in finished form right there

    The intent was primarily to identify the exact error. The runtime reporting (on my system) for an uncaught exception is totally uninformative. It just says "int thrown". Which int? As you can see, there are three possibilities. To identify the error, I need to catch it.

    The reason I highlighted "You can only use valis if construction succeeds" is because that's not true. You can't use it even if it succeeds, because it goes out of scope with the try block.

    The other situation where I find this irritating is in class definition:
    Code:
    class whatever {
        SomeClass SomeObj;
    if "SomeObj" requires initialization inside "whatever"s constructor, then it need to be a pointer now too! Why not allow an object to be declared uninitialized? This must be a very common scenario (class members that are objects requiring initialization in the constructor).

    I'd write Bjarne a letter explaining how daft he is, but I imagine he is not so daft and this is just impossible to implement for one reason or another, because everyone must have been aware of it for a long time.
    Last edited by MK27; 03-21-2010 at 02:27 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #21
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    The reason I highlighted "You can only use valis if construction succeeds" is because that's not true. You can't use it even if it succeeds, because it goes out of scope with the try block.
    It is true because you can use it in the try block.

    Quote Originally Posted by MK27
    if "SomeObj" requires initialization inside "whatever"s constructor, then it need to be a pointer now too! Why not allow an object to be declared uninitialized? This must be a very common scenario (class members that are objects requiring initialization in the constructor).
    You would just use the constructor initialisation list to invoke the member variable's appropriate constructor.

    If you really want, you can design the class to use two stage construction, i.e., the constructor does not initialise the object, rather, an initialisation function is provided for the task. But this means that it is possible to have objects with invalid state, and this can be Bad Thing.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #22
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    You would just use the constructor initialisation list to invoke the member variable's appropriate constructor.
    That's not inside the constructor, eg, for example: the member object is optional and may throw it's own exception, which you want to catch in the constructor. I just noticed you can do that (use try) in the initialization list, but I'm guessing there are some things you can't do.

    In the end I did go with two stage construction (the first stage is not empty, it sets a local "errno" which is examined by the second stage before execution proceeds).

    As for the member pointer, here's the actual situation: It's optional based on a parameter. I haven't tried yet because I'm not sure how it should look, but can you put an if/else block in an initialization list? Eg, if the param is NULL, I don't want to initialize the object at all -- but I'm guessing "an uninitialized object" cannot exist in C++, just an initialized pointer? This is not a big deal, just want to make sure I am not giving up too soon or missing something.
    Last edited by MK27; 03-21-2010 at 02:49 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #23
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    That's not inside the constructor, eg, for example: the member object is optional and may throw it's own exception, which you want to catch in the constructor.
    If the member is optional then it makes sense for the member to be a pointer.

    Quote Originally Posted by MK27
    I just noticed you can do that (use try) in the initialization list, but I'm guessing there are some things you can't do.
    Read GotW #66: Constructor Failures.

    Quote Originally Posted by MK27
    In the end I did go with two stage construction (the first stage is not empty, it sets a local "errno" which is examined by the second stage).
    So you are not satisfied with the solution that involves just writing the code in the try block? That is one of the reasons to use exceptions in the first place, i.e., the normal flow of control can be written normally, with exceptions handled further down.

    Quote Originally Posted by MK27
    As for the member pointer, here's the actual situation: It's optional based on a parameter. I haven't tried yet because I'm not sure how it should look, but can you put an if/else block in an initialization list?
    No, but for this you can use the constructor body.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #24
    Registered User
    Join Date
    Mar 2010
    Posts
    15
    Quote Originally Posted by laserlight View Post
    If you really want, you can design the class to use two stage construction, i.e., the constructor does not initialise the object, rather, an initialisation function is provided for the task. But this means that it is possible to have objects with invalid state, and this can be Bad Thing.
    I believe you are wrong. You cannot avoid constructing members when the container is constructed. If you don't do so explicitly in the initializer list, the default constructors will be called. This goes for member objects as well as base classes.

  10. #25
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by mustermeister
    I believe you are wrong. You cannot avoid constructing members when the container is constructed.
    I am right, because I talked about avoiding initialisation, not construction. If you can arrange to use members whose constructors do not initialise them (or initialise them to a known invalid state), then you can do two stage construction.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #26
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    So you are not satisfied with the solution that involves just writing the code in the try block? That is one of the reasons to use exceptions in the first place, i.e., the normal flow of control can be written normally, with exceptions handled further down.
    Nah -- the whole program is about the valis object, I'm not putting it all into a try block. I suppose a try is not really needed, the program has to fail anyway. Except that it does allow the exception to be identified -- without a try/catch it says nothing beyond the fact that "an exception occurred".

    Maybe this is actually an inappropriate use of exceptions -- it is easy enough to use an errno type variable or some some check() function to make sure the initialized object is in good working order (in fact I took all the exceptions out and had the init() func return a value for error checking).

    I'm also guessing they are for use in libraries and such so that the onus is put on the user: if you don't do error checking in the form of try/catch, then your program will just fail (rather than providing error reporting which can be ignored or left unchecked).

    No, but for this you can use the constructor body.
    Ie, a member pointer. So definitely: no such thing as an uninitialized object in C++?
    Last edited by MK27; 03-21-2010 at 03:28 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  12. #27
    Registered User
    Join Date
    Mar 2010
    Posts
    15
    Quote Originally Posted by MK27 View Post
    That's not inside the constructor, eg, for example: the member object is optional and may throw it's own exception, which you want to catch in the constructor. I just noticed you can do that (use try) in the initialization list, but I'm guessing there are some things you can't do.
    You CAN'T catch an exception from a member object IN the constructor. It seems permitted to do so in the initializer list, but that's terribly bad programming practice. Never do so! You don't WANT to do it, because the construction of the container SHOULD fail when the construction of some member does.

  13. #28
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by MK27
    Nah -- the whole program is about the valis object. So a try is not really needed, the program has to fail anyway. Except that it does allow the exception to be identified -- without a try/catch it says nothing beyond the fact that "an exception occurred".
    I do not understand: what is the point of your program?

    Quote Originally Posted by MK27
    Maybe this is actually an pointless use of exceptions -- it is easy enough to use an errno type variable or some some check() function to make sure the initialized object is in good working order.
    This goes back to the debate between error codes and exceptions. It is easy enough to check, but a check might be forgotten. On the other hand, carelessness can also lead to a lack of exception safety.

    Quote Originally Posted by MK27
    Ie, a member pointer. So definitely: no such thing as an uninitialized object in C++?
    There are, but the norm is to avoid them.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #29
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by mustermeister View Post
    You CAN'T catch an exception from a member object IN the constructor. It seems permitted to do so in the initializer list, but that's terribly bad programming practice. Never do so! You don't WANT to do it, because the construction of the container SHOULD fail when the construction of some member does.
    Not if the member object is unessential. As I said, in this case it's optional based on a parameter. If the construction fails, I can just leave the pointer null and the class method will function as if that option had not been selected in the first place.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #30
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by laserlight View Post
    I do not understand: what is the point of your program?
    Well, it's a server, one of a few variations which all use the same base class. So each such server program contains one server object providing the base functionality.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Initializing constant object member of a class
    By Canadian0469 in forum C++ Programming
    Replies: 3
    Last Post: 12-03-2008, 08:05 PM
  2. Telling a shared_ptr not to delete object?
    By TriKri in forum C++ Programming
    Replies: 5
    Last Post: 08-16-2008, 04:26 AM
  3. ERRPR: Object reference not set to an instance of an object
    By blackhack in forum C++ Programming
    Replies: 1
    Last Post: 07-13-2005, 05:27 PM
  4. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 13
    Last Post: 10-31-2002, 02:56 PM
  5. Set Classes
    By Nicknameguy in forum C++ Programming
    Replies: 3
    Last Post: 10-21-2002, 07:40 PM