Berkeley CSUA MOTD:Entry 43824
Berkeley CSUA MOTD
 
WIKI | FAQ | Tech FAQ
http://csua.com/feed/
2025/05/25 [General] UID:1000 Activity:popular
5/25    

2006/7/28-8/2 [Computer/SW/Languages/C_Cplusplus] UID:43824 Activity:nil
7/27    In C/C++, how come some parameters have "mconst" before the type
        and some don't? I don't see how it changes anything. -newbie
        \_ If it's a pointer or reference, then you can't change the contents.
        \_ Nicely summarized here:
           http://www.parashift.com/c++-faq-lite/const-correctness.html
        \_ The answer is 47. -proud American
2025/05/25 [General] UID:1000 Activity:popular
5/25    

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 (8192 bytes)
www.parashift.com/c++-faq-lite/const-correctness.html
It means using the keyword const to prevent const objects from getting mutated. For example, if you wanted to create a function f() that accepted a std::string, plus you want to promise callers not to change the caller's std::string that gets passed to f(), you can have f() receive its std::string parameter... This check is done entirely at compile-time: there is no run-time space or speed cost for the const. In the pass by value case (f3, the called function gets a copy of the caller's std::string. This means that f3() can change its local copy, but the copy is destroyed when f3() returns. In particular f3() cannot change the caller's std::string object. As an opposite example, if you wanted to create a function g() that accepted a std::string, but you want to let callers know that g() might change the caller's std::string object. In this case you can have g() receive its std::string parameter... Thus they can pass their std::string to any of the f() functions, but only f3() (the one that receives its parameter "by value") can pass its std::string to g1() or g2(). If f1() or f2() need to call either g() function, a local copy of the std::string object must be passed to the g() function; the parameter to f1() or f2() cannot be directly passed to either g() function. In particular, no changes will be made to the const parameter that was passed by reference to f1(). How is "const correctness" related to ordinary type safety? Declaring the const-ness of a parameter is just another form of type safety. If you find ordinary type safety helps you get systems correct (it does; especially in large systems), you'll find const correctness helps also. Should I try to get things const correct "sooner" or "later"? Back-patching const correctness results in a snowball effect: every const you add "over here" requires four more to be added "over there." non-const member function called mutate(), saying p->mutate() is an error (the error is caught by the compiler; no run-time tests are done, which means const doesn't slow your program down). non-const member function called mutate(), saying xmutate() is an error (the error is caught by the compiler; no run-time tests are done, which means const doesn't slow your program down). In other words, "Fred& const x" is functionally equivalent to "Fred& x". Since you're gaining nothing by adding the const after the &, you shouldn't add it since it will confuse people. const Fred& x However, the real question is which should be used. Answer: absolutely no one should pretend they can make decisions for your organization until they know something about your organization. there is no "right" answer for all organizations, so do not allow anyone to make a knee-jerk decision in either direction. For example, some organizations value consistency and have tons of code using const Fred&; for those, Fred const& would be a bad decision independent of its merits. There are lots of other business scenarios, some of which produce a preference for Fred const&, others a preference for const Fred&. Use a style that is appropriate for your organization's average maintenance programmer. Not the gurus, not the morons, but the average maintenance programmer. Unless you're willing to fire them and hire new ones, make sure that they understand your code. Make a business decision based on your realities, not based on someone else's assumptions. You'll need to overcome a little inertia to go with Fred const&. Most current C++ books use const Fred&, most programmers learned C++ with that syntax, and most programmers still use that syntax. That doesn't mean const Fred& is necessarily better for your organization, but it does mean you may get some confusion and mistakes during the transition and/or when you integrate new people. Some organizations are convinced the benefits of Fred const& outweigh the costs; const Fred* x However, the real question is which should be used. Answer: absolutely no one should pretend they can make decisions for your organization until they know something about your organization. there is no "right" answer for all organizations, so do not allow anyone to make a knee-jerk decision in either direction. For example, some organizations value consistency and have tons of code using const Fred*; for those, Fred const* would be a bad decision independent of its merits. There are lots of other business scenarios, some of which produce a preference for Fred const*, others a preference for const Fred*. Use a style that is appropriate for your organization's average maintenance programmer. Not the gurus, not the morons, but the average maintenance programmer. Unless you're willing to fire them and hire new ones, make sure that they understand your code. Make a business decision based on your realities, not based on someone else's assumptions. You'll need to overcome a little inertia to go with Fred const*. Most current C++ books use const Fred*, most programmers learned C++ with that syntax, and most programmers still use that syntax. That doesn't mean const Fred* is necessarily better for your organization, but it does mean you may get some confusion and mistakes during the transition and/or when you integrate new people. Some organizations are convinced the benefits of Fred const* outweigh the costs; A member function that inspects (rather than mutates) its object. A const member function is indicated by a const suffix just after the member function's parameter list. Member functions with a const suffix are called "const member functions" or "inspectors." Member functions without a const suffix are called "non-const member functions" or "mutators." The trailing const on inspect() member function means that the abstract (client-visible) state of the object isn't going to change. This is slightly different from promising that the "raw bits" of the object's struct aren't going to change. Another (important) insight from this aliasing issue: pointing at an object with a pointer-to-const doesn't guarantee that the object won't change; it promises only that the object won't change via that pointer. What do I do if I want a const member function to make an "invisible" change to a data member? By saying the changes are "innocuous," I mean that the changes wouldn't be visible from outside the object's interface (otherwise the member function would be a mutator rather than an inspector). When this happens, the data member which will be modified should be marked as mutable (put the mutable keyword just before the data member's declaration; This tells the compiler that the data member is allowed to change during a const member function. If your compiler doesn't support the mutable keyword, you can cast away the const'ness of this via the const_cast keyword (but see the NOTE below before doing this). Therefore you can use self to modify the object pointed to by this. NOTE: there is an extremely unlikely error that can occur with const_cast. It only happens when three very rare things are combined at the same time: a data member that ought to be mutable (such as is discussed above), a compiler that doesn't support the mutable keyword, and an object that was originally defined to be const (as opposed to a normal, non-const object that is pointed to by a pointer-to-const). Although this combination is so rare that it may never happen to you, if it ever did happen the code may not work (the Standard says the behavior is undefined). If you ever want to use const_cast, use mutable instead. In other words, if you ever need to change a member of an object, and that object is pointed to by a pointer-to-const, the safest and simplest thing to do is add mutable to the member's declaration. Please don't write and tell me that version X of compiler Y on machine Z allows you to change a non-mutable member of a const object. I don't care -- it is illegal according to the language and your code will probably fail on a different compiler or even a different version (an upgrade) of the same compiler. This can happen only in rare cases (when the object is constructed in the scope of the const member function invocation, and when all the non-const me...