Berkeley CSUA MOTD:Entry 22334
Berkeley CSUA MOTD
 
WIKI | FAQ | Tech FAQ
http://csua.com/feed/
2025/07/10 [General] UID:1000 Activity:popular
7/10    

2001/9/6 [Computer/SW/Languages/C_Cplusplus] UID:22334 Activity:high
9/5     In C++ how do you detect that a constructor failed to execute
        successfully? I've got this ugly hack that sets an instance
        variable which my code can check, but I'm looking for something
        a bit more elegant. My C++ fu is really weak as I've been a
        C programmer way too long.
        \_ Throw an exception from the constructor if it fails, and catch
           the exception wherever you want to deal with it.
          |_ Thought that was in Java.
        \_ The above response is the preferred method. --jsjacob
           http://www.parashift.com/c++-faq-lite/exceptions.html#[17.2]
           \_ Thanks. Looks like my soln. was equivalent to the "zombie"
              idea, but I'll try to use an execption instead.
        \_ It returns NULL?
           \_ Constructors do not return anything.
           \_ Your an idiot. [sic]
2025/07/10 [General] UID:1000 Activity:popular
7/10    

You may also be interested in these entries...
2011/3/7-4/20 [Computer/SW/Languages/C_Cplusplus] UID:54056 Activity:nil
3/7     I have a C question.  I have the following source code in two identical
        files t.c and t.cpp:
                #include <stdlib.h>
                int main(int argc, char *argv[]) {
                  const char * const * p1;
                  const char * * p2;
	...
2004/12/14-15 [Computer/SW/Compilers] UID:35291 Activity:moderate
12/14   If I have a C function like this
        void foo(void) {
          static const char unused1[] = "one";
          const char * const unused2 = "two";
          ...... some code ......
          return;
	...
2004/8/10-11 [Computer/SW/Languages/C_Cplusplus, Computer/SW/Compilers] UID:32805 Activity:high
8/10    C question.  Is there anything wrong with the following?
        const my_struct_t **pp;
        pp = malloc(sizeof(my_struct_t *));
        pp = realloc(pp, sizeof (my_struct_t *) * 2);
        "gcc -Wall" doesn't complain.  But the M$ compiler (cl.exe) complains
        about the realloc line:
	...
2004/5/28-29 [Computer/SW/Compilers] UID:30481 Activity:nil
5/28    I just found out that bison inserts these lines of code
                #ifndef __cplusplus
                #ifndef __STDC__
                #define const
                #endif
                #endif
	...
2003/12/8-9 [Computer/SW/Languages/C_Cplusplus] UID:11356 Activity:nil
12/8    c++ question, how do I overload << in my class so it will handle
        endl? ie: myclass << "some string" << endl
        I know how to do the "some string" part:
                myclass & operator << (const char * s);
        what about endl?
        Thanks!!
	...
2003/9/10 [Computer/SW/Languages/C_Cplusplus] UID:29529 Activity:nil
9/10    Stupid question: how do I reference a C callback?
        int mycompare(void const *a, void const *b) { ... }
        qsort(msg, sizeof(Msg), numMsgs, mycompare);
        I get
        "Type error in argument 4 to `qsort'; calling convention mismatch."
        \_ There's nothing wrong in the you reference it.  However, you should
	...
2003/4/22-23 [Computer/SW/Languages/C_Cplusplus] UID:28189 Activity:insanely high
4/22    Anyone know a good link that explains all of C++'s use of the
        keyword mconst?
        \_ http://www.parashift.com/c++-faq-lite
           Search for const in the text box.
           Search for mconst in the text box.
           \- perfection
	...
2002/7/13-15 [Computer/SW/Languages/C_Cplusplus] UID:25351 Activity:moderate
7/13    how do i pass variables to the system in C ?  e.g.
         system("echo input is %s", argv[1]);
        results in "input is %s" but I want the system to see argv[1]
        (I know i can just use printf, but not for what i really want to do).
        \_ sprintf into array, pass array to system?
        \_ so write your own function that takes a variable number of
	...
2001/9/23-24 [Computer/SW/Languages/C_Cplusplus] UID:22600 Activity:moderate
9/23    let's say there's a C library you want to use called libmdn.so.
        I think to load it you'd go something like:
        static { System.loadLibrary("mdn"); }
        However, let's say that a function call looked like this:
        mdn_result_t mdn_encodename(int actions, const char
        *from, char *to, size_t tolen)
	...
2001/3/17-18 [Computer/SW/Languages/C_Cplusplus] UID:20827 Activity:high
3/16    Why does so much C sample code use #define instead of const?
        \_ because any good C code will use a bunch of preprocessor
           anyways. you can't be a good C programmer and eschew the
           preprocessor. For that, you need a language which fills those
           gaps with other constructs (c++ templates go a long way to
           obviate the need for preprocessor for example). you
	...
2000/6/21-22 [Computer/SW/Languages/C_Cplusplus] UID:18506 Activity:very high
6/20    I have a variable inside a struct.  I want to be able to initialize
        that variable ONCE and not write to it again.  Any subsequent writes
        should not be permitted.  Is there a way to do that in C?  I know
        about "const int foo = 5;" but the value I need to pass in is dynamic
        and happens at runtime.  Declaring a variable as const doesn't let
        me assign anything to it at all.  Thanks.
	...
Cache (5589 bytes)
www.parashift.com/c++-faq-lite/exceptions.html#[17.2]
The commonly used alternative to try / catch / throw is to return a return code (sometimes called an error code) that the caller explicitly tests via some conditional statement such as if. For example, printf(), scanf() and malloc() work this way: the caller is supposed to test the return value to see if the function succeeded. Although the return code technique is sometimes the most appropriate error handling technique, there are some nasty side effects to adding unnecessary if statements: * Degrade quality: It is well known that conditional statements are approximately ten times more likely to contain errors than any other kind of statement. So all other things being equal, if you can eliminate conditionals / conditional statements from your code, you will likely have more robust code. Basically if you don't exercise every branch point, there will be instructions in your code that will never have been executed under test conditions until they are seen by your users/customers. So compared to error reporting via return-codes and if, using try / catch / throw is likely to result in code that has fewer bugs, is less expensive to develop, and has faster time-to-market. Of course if your organization doesn't have any experiential knowledge of try / catch / throw, you might want to use it on a toy project first just to make sure you know what you're doing -- you should always get used to a weapon on the firing range before you bring it to the front lines of a shooting war. Constructors don't have a return type, so it's not possible to use return codes. The best way to signal constructor failure is therefore to throw an exception. If you don't have the option of using exceptions, the "least bad" work-around is to put the object into a "zombie" state by setting an internal status bit so the object acts sort of like it's dead even though it is technically still alive. You'll also want to add an if to your other member functions: if the object is a zombie, do a no-op or perhaps something more obnoxious. Certainly you should prefer exceptions over zombie objects, but if you do not have the option of using exceptions, zombie objects might be the "least bad" alternative. Here's why (buckle your seat-belts): The C++ rule is that you must never throw an exception from a destructor that is being called during the "stack unwinding" process of another exception. For example, if someone says throw Foo(), the stack will be unwound so all the stack frames between the throw Foo() and the } catch (Foo e) { will get popped. During stack unwinding, all the local objects in all those stack frames are destructed. If one of those destructors throws an exception (say it throws a Bar object), the C++ runtime system is in a no-win situation: should it ignore the Bar and end up in the } catch (Foo e) { where it was originally headed? Should it ignore the Foo and look for a } catch (Bar e) { handler? There is no good answer -- either choice loses information. So the C++ language guarantees that it will call terminate() at this point, and terminate() kills the process. The easy way to prevent this is never throw an exception from a destructor. But if you really want to be clever, you can say never throw an exception from a destructor while processing another exception. But in this second case, you're in a difficult situation: the destructor itself needs code to handle both throwing an exception and doing "something else", and the caller has no guarantees as to what might happen when the destructor detects an error (it might throw an exception, it might do "something else"). Of course the word never should be "in quotes" since there is always some situation somewhere where the rule won't hold. But certainly at least 99% of the time this is a good rule of thumb. Every data member inside your object should clean up its own mess. If a constructor throws an exception, the object's destructor is not run. If your object has already done something that needs to be undone (such as allocating some memory, opening a file, or locking a semaphore), this "stuff that needs to be undone" must be remembered by a data member inside the object. For example, rather than allocating memory into a raw Fred* data member, put the allocated memory into a "smart pointer" member object, and the destructor of this smart pointer will delete the Fred object when the smart pointer dies. You can also 26 use smart pointers to "point" to disk records or objects on other machines. By the way, if you think your Fred class is going to be allocated into a smart pointer, be nice to your users and create a typedef within your Fred class: #include <memory> class Fred { public: typedef std::auto_ptr<Fred> Ptr; If what you really want to do is work with strings, don't use an array of char in the first place, since 32 arrays are evil. For example, suppose you want to get a copy of a string, fiddle with the copy, then append another string to the end of the fiddled copy. The array-of-char approach would look something like this: void userCode(const char* s1, const char* s2) { char* copy = new char strlen(s1) + 1 ; Your compiler probably supplies a string-like class, and it's probably just as fast and certainly it's a lot simpler and safer than the char* code that you would have to write yourself. For example, if you're using the std::string class from the 33 standardization committee, your code might look something like this: #include <string> // Let the compiler see std::string void userCode(const std::string& s1, const std::string& s2) { std::string copy = s1;