Monday, April 25, 2011

Is 'private' a C keyword?

This question is merely to settle a wager, because I already know the answer and this seemed quicker than reading the standard:

Are 'private' or 'public' keywords in ANSI C (or any other C for that matter), or were they only added in C++ (and Java, C#, ...)?

From stackoverflow
  • private is not a C89 or C99 keyword. See C Programming/Reference Tables on Wikibooks*.

    Also, C has nothing** to do with Java and C# (and, really, not C++ either). However, the converse is not true -- C++ grew from C, for example.

    * Better reference needed!
    ** Actually, C89 "borrowed" the const and volatile keywords from C++. Likewise, C99 "borrowed" the inline keyword, and also added _Bool and _Complex (like C++'s bool andcomplex, respectively) [citation-needed].

    ripper234 : They are evolutions of C, and much of their syntax sprang from C.
    Johannes Schaub - litb : C++ has no imaginary. but you can instead show "const" as another example where C got ideas from C++ (source: http://www.lysator.liu.se/c/rat/c5.html#3-5-3). another one is function prototypes (#3-5-4)
    strager : @litb, I don't remember The Dark Ages before C99. I'll update my answer with your information. (Sorry for the misinformation about imaginary!)
    Johannes Schaub - litb : by the way, good answer. +1 :)
  • some people do:

    • #define public
    • #define private static

    but it is not a C keyword.

    EDIT:

    For those who think it is a bad idea to do that, I would agree... but it does explain why someone might think "public" or "private" were C keywords.

    For those who think it won't compile in C... try this:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define public
    #define private static
    
    private void sayHello(void);
    
    public int main(void)
    {
        sayHello();
    
        return (EXIT_SUCCESS);
    }
    
    private void sayHello(void)
    {
       printf("Hello, world\n");
    }
    

    For those who think it won't compile in C++, yes the above program will. (Edit) Well actually it is undefined behaviour due to this part of the C++ standard:

    A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords.

    So the example above and below are not required to do anything sane in C++, which is a good thing. My answer still is completely valid for C (until is is proved to be wrong! :-)

    In the case of C++ a class with private members you can do a similar (abuse) like this:

    #include <cstdlib>
    #define private public
    #include "message.hpp"
    
    int main()
    {
        Message msg;
    
        msg.available_method();
        msg.hidden_method();
    
        return (EXIT_SUCCESS);
    }
    
    #ifndef MESSAGE_H
    #define MESSAGE_H
    
    #include <iostream>
    
    class Message
    {
    private: 
        void hidden_method();
    
    public: 
        void available_method();
    };
    
    inline void Message::hidden_method()
    {
        std::cout << "this is a private method" << std::endl;
    }
    
    inline void Message::available_method()
    {
        std::cout << "this is a public method" << std::endl;
    }
    
    #endif
    
    jmucchiello : They shouldn't do that.
    TofuBeer : I didn't say I supported it... some people stick their heads in ovens too... but you might see code that has done it
    Dan Olson : It wouldn't compile in C/C++.
    Johannes Schaub - litb : Dan, are you sure? i think it would, but it is UB (undefined behavior) as soon as you include a standard header file. so it's probably not that useful :)
    strager : @litb, It wouldn't compile in common C++ code because "private:" would be turned into ":", which would result in a syntax error. @Dan, C/C++ isn't a language. It would compile fine in C, unless you're including some C++ header (in which case guards should be in place anyway, or the user is insane).
    strager : I believe @TofuBeer was referring to code like this: public void printHelloWorld(); private int messWithGlobals_EVIL(bool areYouSerious);
    Dan Olson : static keyword doesn't share private keyword's semantics in C++. I could #define purple static and make all my methods "purple" and this would be just as useful.
    TofuBeer : @Dan I don't see your point... are you saying that my code is wrong in some way (it isn't my code by the way, but I have seen it done before).
    Johannes Schaub - litb : oh wait i was refering to C++ when i said "i think it would, but it is UB". well in C that of course is not UB but alright. @strager, it depends whether you actually include something that uses "public:" of course :) @tofu, so your first program is *not* required to compile.it can fail aswell in C++
    TofuBeer : @litb thanks for pointing out that from the standard... updating answer
  • No, C doesn't have encapsulation -- "information hiding". C++ and the other OOP languages introduced it.

    strager : "The other OOP languages" -- I doubt C++, Java, or C# introduced encapsulation. (I could be wrong, though...)
    jmucchiello : In the phrase "introduced it", aaron's 'it' refers to the keyword 'private' not the concept of encapsulation.
    strager : @joe_mucchiello, That is not clear from his statement.
    Pete Kirkham : C has better encapsulation than C++. Unless you use the pImpl idiom in C++, every client of an object in C++ is dependent on its full type.
    strager : @Iraimbilanja, Very good point. @Pete, Isn't using 'plmpl' similar to creating static globals, but with types? Also, aren't all C structures the same as C++ ones (with less goodies)? In that case, your argument has no basis... I'd say encapsulation (through hiding) is equivelent in both languages.
    ashawley : @Iraimbilanja, opaque pointers hide information for recompiling, but they don't restrict access, and static globals are just a lexical scoping hack.
  • The easiest way to settle this might have been to actually try using either with an ANSI/C89/C99 compiler (like gcc) :) A keyword needs no headers ;)

    strager : Not all of C99 is implemented in gcc, IIRC. Nor MS's compiler.
    Jonathan Leffler : And additionally, GCC implements features not in the standard. You'd have to use -std=c89 (or -std=c99) and -pedantic.
    Kristopher Johnson : "It compiles" or "it doesn't compile" have nothing at all to do with whether something is part of a programming-language standard.
    Tim Post : @Kristopher Johnson: How people actually ___use___ the language is equally irrelevant?

0 comments:

Post a Comment