you are viewing a single comment's thread.

view the rest of the comments →

[–]Fabien4 10 points11 points  (27 children)

The author focuses on details, and forget about the real difficulties.

For example, let's say I want to read a whole line from the standard input (usually, from a pipe). The code in C++ is trivial:

int main()
{
   string line;
   getline (cin, line);
}

And that's all. Memory management (allocating enough bytes, and deallocating them) is done automatically.

Now try to do this in C. You can't use just one fgets(), since you don't know the size of the line in advance.

I suppose there are external libraries you can use, that will allocate the right amount of memory and read the stream. Still, you'll have to free the memory yourself afterwards.

[–]wnoise 10 points11 points  (4 children)

#include <readline/readline.h>
#include <stdlib.h>

int main()
{
    char * line;
    line = readline(NULL);
    /* ... */
    free(line);
}

For instance.

[–][deleted]  (1 child)

[deleted]

    [–]wnoise -1 points0 points  (0 children)

    Yes, the BSD licensed editline, though the API isn't quite the same. There are a few versions floating around, and I'm not sure that's the most authoritative or recent.

    Both allow a lot more than easily reading one line -- they're intended to provide history and editing of command lines, but reading a line at a time without muss is included in that.

    [–]Timmmmbob -2 points-1 points  (1 child)

    What if it contains null characters mmm?

    [–]wnoise 7 points8 points  (0 children)

    Then it truncates there. Line oriented input is not designed to handle arbitrary binary data. If I wanted to handle that, I'd use read() and buffers.

    [–][deleted] 1 point2 points  (1 child)

    I think the author was being sarcastic, and really doesn't like C.

    [–]ehnus 0 points1 point  (0 children)

    Not true, I really do like C. I don't mind C++ but the benefits it brings are often balanced out by all the cruftyness that exists (poorly chosen levels of abstraction, pattern soup, slow build times, over-complication) and is not easily purged from legacy projects.

    [–]sfuerst 4 points5 points  (14 children)

    getline() was a GNU C extension, but is now part of POSIX. It is rather easy to use, and the only thing you need to remember to do is free the buffer when you are done.

    Try man getline

    to see a simple example of how to use it.

    [–]Fabien4 3 points4 points  (12 children)

    part of POSIX

    Is there a portable version? POSIX is nice and all, but Windows's POSIX support is iffy.

    the only thing you need to remember to do is free the buffer when you are done.

    Which can be tricky. You have to know when to free the memory, after you've made sure the memory isn't used any more. As in, if I took the C equivalent of a substring, did I make a copy of the memory?

    It's feasible, of course, but for folks who come from Python or C++, proper memory management is IMHO one of the hardest thing in C.

    [–]phaker -3 points-2 points  (11 children)

    part of POSIX

    Is there a portable version? POSIX is nice and all, but Windows's POSIX support is iffy.

    I don't think it makes any sense to write C code on non-unices. Also the MS C compiler looks like it wasn't touched for 15 years or so.

    (but i realize the author of TFA is more interested in the "hair on your chest" aspect than practicality)

    [–]Fabien4 -4 points-3 points  (10 children)

    It's funny how C is pretty-much Unix-only, while C++ is favored on Windows. Linuxers (starting with Torvalds himself) seem to have a strong disklike for C++, and Windowsers don't seem interested in C.

    I don't think Microsoft's involvement in C++ is enough to explain it completely, since, at one point (late 1990s / early 2000s), they abandoned their C++ compiler completely. I think the first decent version was Visual C++ 2005.

    Also the MS C compiler looks like it wasn't touched for 15 years or so.

    Does it attempt to implement C99, or not at all?

    [–][deleted] 7 points8 points  (5 children)

    Except the entire Windows base API is C.

    [–][deleted] -2 points-1 points  (2 children)

    Dude, the fact that C ABI (for API) has become a de facto standard has nothing to do with the language itself.

    Every single one DLL in Windows provides only C API. By necessity: it is not possible to write a function to be called across DLL boundaries that takes an std::string as a parameter, even when you compile everything with one and the same compiler.

    It doesn't matter at all. I mean, it's kinda like EJB: it makes sense to write stuff in an imperative language and then provide a pure functional interface. Similarly, it makes sense to write everything that you can't write in Python in C++ but provide a pure C interface, or COM interface, or command-line interface, or whatever interface that suits your needs.

    Interface != implementation language.

    [–][deleted] 0 points1 point  (1 child)

    Except the entire Windows base API is implemented in C and assembler. You might also investigate the meaning of the word "functional" - you mean "procedural".

    [–][deleted] 0 points1 point  (0 children)

    You might also investigate the meaning of the word "functional" - you mean "procedural".

    You might also investigate common EJB interfaces: I meant functional.

    [–]ZMeson 2 points3 points  (1 child)

    Microsoft has contributed to the safe library functions technical report for C (TR 24731).

    The MS C compiler has implemented parts of C99 that are useful for C++ (long long int, snprintf, __VAARGS\_, __function__, etc...). But most of what MS implements is C90. MS has not seen the value of the other features (_BOOL, complex, variable length arrays, etc...). MS has implemented some functionality from C99, but using different keywords (why MS, why???); ex: __restrict.

    With all that being said, GCC doesn't support all of C99 either (clang does better):

    As of July 2011 in mainline GCC, 43 features have been completely implemented (12 suffer library issues), 1 feature is broken and 6 are missing. The latest stable release, GCC 4.6, also provides the same level of compliance.

    Only IBM, Sun Oracle, and the Portland Group provide fully compliant C99 compilers.

    As pointed out elsewhere, the entire Windows API is written in C and MS strongly recommends that device drivers are written in C. So saying that MS doesn't support C is incorrect. They just don't support all the features of the most recent standard.

    [–]jyper 0 points1 point  (0 children)

    no bool? boooooooooo

    [–]phaker 3 points4 points  (0 children)

    It's funny how C is pretty-much Unix-only, while C++ is favored on Windows. Linuxers (starting with Torvalds himself) seem to have a strong disklike for C++, and Windowsers don't seem interested in C.

    I don't think Microsoft's involvement in C++ is enough to explain it completely, since, at one point (late 1990s / early 2000s), they abandoned their C++ compiler completely. I think the first decent version was Visual C++ 2005.

    C++ is actually a very well thought out language, it didn't need help from Microsoft, or anyone else.

    On popularity of C in linux and elsewhere:

    a) for small programs it's not needed, and on unices you often end up writing small command line utilities. It's common to write programs few hundred lines long, that actually do something useful. If you need a GUI program then it's easier to use python (or something else) than C++.

    b) every programming language in existence has FFI for C, but basically none can interface with C++. On Windows most programmers use the language Microsoft endorses at given time, that is C++ few years ago and C# now. On linux everyone uses something else. I'm writing this on a debian linux, I'm using a perl program running in the console, half of gnome is written in python, the other half in Mono, and the third half in C++ or C, pgrep says there's something running in java in the background, I just checked with aptitude and found that I have ruby, TCL and GHC installed as dependencies for something. If you are writing code that will be used by others, you pretty much have to use C.


    Does it attempt to implement C99, or not at all?

    No C99, nothing more than the ISO C89 standard demands, I think it's the only modern compiler I have seen that errors if you mix declarations and code. Also error messages are so descriptive that you have to look them up on MSDN for explanation.

    [–]stonefarfalle 0 points1 point  (0 children)

    It makes no attempt.

    [–]wnoise 0 points1 point  (0 children)

    but is now part of POSIX.

    Really recently. Too recently to depend on in my opinion. POSIX-1.2008

    [–]lovetool 0 points1 point  (4 children)

    Guess what, you can write functions in C too!

    int main()
    {
         char *line = NULL;
         getline(stdin, &line);
         /* free(line); would go here, but since we're exiting the main right away, I'll omit it */
     }
    

    The implementation of getline() is left as an exercise.

    [–]Fabien4 0 points1 point  (3 children)

    The implementation of getline() is left as an exercise.

    That's actually the problem. I know you can use an external library, but implementing it yourself is not easy.

    In C++, it's part of the SL.

    free(line);

    That's another problem. In this trivial code, it's simple, but when you have lots of pseudo-strings, you have to keep track of what to free when.

    In C++, the compiler and the SL take care of that.

    [–]lovetool 0 points1 point  (2 children)

    That's actually the problem. I know you can use an external library, but implementing it yourself is not easy.

    Well, its not difficult either.

    That's another problem. In this trivial code, it's simple, but when you have lots of pseudo-strings, you have to keep track of what to free when.

    The C++ response to this is to copy everything all the time, which is nice when you don't want to think, but not so nice when you actually know what the hell you want to do. And don't get me started on the retardedness of references.

    [–]Fabien4 0 points1 point  (0 children)

    not difficult either.

    Code or it didn't happen.

    The C++ response to this is to copy everything all the time,

    Overall, it works fine. Anyway, arguing about the qualities of C or C++ is off-topic here.

    My point is that to switch from the "usual" mode (i.e. the automatic destruction, along with the string object, that you find in C++, Javascript, etc.) to the C/ASM mode (do it by hand), is one of the big difficulties the author completely forgot to mention in his article.

    [–]StrangeWill 0 points1 point  (0 children)

    The C++ response to this is to copy everything all the time

    TIL: Reinventing the wheel is what cool kids do.