Talk:C (programming language)/Archive 1

Notes on small changes
"method" is an unusual word to use for C functions.

"The  method is required in all C programs that are intended to be executed, but it is not necessary for those that are not so intended." sounds like a joke; in fact, AFAIK the difference between a "C program" and a bunch of C code that's not a "program" is precisely the presence of main. Even if I'm wrong and the sentence is perfectly correct, I don't think that sentence will help readers of this article.

Dereferencing a pointer does not change what that pointer refers to, but produces a new value which is distinct from the pointer's value, and which refers to the data at the address stored in the pointer. But that's too long-winded for the article; I think my new phrasing is okay.

The fact that void pointers exist does not "indicate" that they point to an object of unknown type; the fact that they are CALLED 'void pointers' does, but again that's too long to say and it can be finessed with a rephrase.

I fixed a few grammatical errors too.

DanielCristofani 14:10, 17 May 2005 (UTC)

"ALL" as a dangerous term
A recent editor reverted out an addition of mine, stating:


 * All C compilers ignore // comments; the standard requires it. But that is not particularly relevant here anyway

(My addition was (Many modern C compilers can also ignore the  comment delimiter used by C++ code, although doing so may require a command-line qualifier.)

I'm always amused whenever anyone suggests that all somethings do something or no somethings do something; such a statement is usually wrong. And it's certainly wrong in this case: There's no doubt that the class of C compilers also includes the compilers that implemented only the Old Testament and not just the ANSI standard, and those Old Testament compilers most assuredly do not implement that "//" comment delimiter. So the "modern" part of my comment was absolutely correct. And the portion about requiring a command-line qualifier was also correct; reasonably-recent and definitely ANSI-compliant versions of the Sun Workshop compilers most-assuredly DO require such a qualifier, although GCC doesn't.


 * This depends on what you mean by "C compiler". I usually take it as an implementation of the C standard, and for the sake of clarity, this seems to make the most sense in an encyclopedic article. In which case the statement is provably correct. And if Sun Workshop does not accept it by default, then it's clearly not standards compliant. --Mellum 16:20, 18 May 2005 (UTC)

And, of course, my comment was inserted directly after the explanation of "/* */"-style comments, so it was in a relevant context.


 * However, the point of that paragraph was not to give a complete explanation of comment syntax, but rather to give a brief overview of C's syntax in general; therefore, I considered these obscure details too distracting. But I don't feel very strongly about that. BTW, "//" is not from C++, but from BCPL. --Mellum 16:20, 18 May 2005 (UTC)

So I'm putting it back (although correcting my language as I do so). And if someone wants to go out on the limb and change it from "Many modern C compilers" to "All modern C compilers", more power to you. But you'd better be sure you've inspected all modern C compilers including some rather obscure ones!

Atlant 23:48, 17 May 2005 (UTC)

"remember, C is entirely the work of Dennis Ritchie, I am but a popularizer." (Kernighan in an interview)

Which raises the question: should we say it was "developed" by Thompson and Ritchie? What was Thompson's involvement apart from contributing the B language that C was based on? Maybe it needs a further rephrase...

DanielCristofani 23:31, 6 Jun 2005 (UTC)

Feature list - Metaprogramming
I disagree with the list of features C does not have - in that C supports Metaprogramming.

In the article on Metaprogramming, listed as an example of Metaprogramming, is the 'Quine' - "a special kind of metaprogram that has its own source as its output". There are plenty of Quines in the C language. Here's an example:

char*f="char*f=%c%s%c;main{printf(f,34,f,34,10);}%c";main{printf(f,34,f,34,10);}

Therefore, by at least this one example, C supports Metaprogramming. Many more are likely to be found as entries for the IOCCC.

Ben-Arba 07:08, Jun 18, 2005 (UTC)


 * The concept of &quot;metaprogramming" is rather difficult to define, as Talk: Metaprogramming shows. Under some loose definitions, even compilation is metaprogramming. I'd say that a C program, in general, cannot reason about or modify its own structure, except maybe with macros, and there only in a primitive sense. Deco 01:03, 19 Jun 2005 (UTC)

But do we have to be in the agreement whether C supports metaprogramming or not? Aside from the difficulty pointed out above, answering this question sounds rather original research. So I think we'd be better off if we simply list features of C and put some example like Ben-Arba gave in the article and let readers decide. -- Taku 06:35, Jun 19, 2005 (UTC)


 * Okay, that's fine, I'll remove it. Deco 07:46, 19 Jun 2005 (UTC)

VfD: C Programming Mistakes
Since the watchers of this page evidently have interest in C, I thought some of you might be interested in commenting on the deletion vote Votes for deletion/C Programming Mistakes for the article C Programming Mistakes. Deco 21:43, 14 July 2005 (UTC)

Removed lint comment
I removed this comment from the Problems with C section:


 * Rather than placing these checks in the compiler, additional tools, such as Lint, were used.

This is true for some such checks, but others are made undecidable by the lack of limitations on the language. This comment misleadingly suggests that all problems with C can be overcome by a sufficiently intelligent tertiary static checking tool, which is false, and that Lint is this tool, which is even more false. Deco 01:28, 15 July 2005 (UTC)


 * I think the point of the original text is that some semantic checks were intentionally left out of the compiler itself, and were intended to be implemented in tools such as lint (I don't personally know with certainty whether or not that is true, but I've heard the same statement elsewhere). I don't think it is suggesting that "all problems with C" can be resolved via the use of a static checker (which is obviously false). Neilc 01:34, 15 July 2005 (UTC)


 * I agree. The reference to Lint should stay, but it should be shown to be only a partial solution.  Something like "Additional tools, such as Lint, were used to attempt to do the checks left out of the compiler"?  --A D Monroe III 01:45, 15 July 2005 (UTC)


 * This is already discussed at sufficient length in the final subsection. I don't feel like it's necessary to reiterate it the section introduction. Deco 02:13, 15 July 2005 (UTC)

About "questionable choices of operator precedence"
Perhaps, this evolved out of a need for optimization? It is often possible to write a complex boolean expression as a binary expression, thereby removing the need for several condition checks and jumps, leading to more compact and faster code.

This is particularly useful in compiler scheduled VLIW architectures, although VLIW may not have been the reason for this

--User:Gauthamg123 04:49, 18 July 2005 (according to edit history)


 * I haven't heard this. I have heard the C operator precedence is baroque and inconsistent, and I agree.  Remember that at the time, operator precedence in general was ill-understood, as shown by other languages developed about the same time (Pascal has only two precedence levels, with logical "and" and binary "and" having the same level, different from logical "or" and binary "or"!).  Perhaps there was some odd reasoning behind the C precedence, but it doesn't affect the fact that users question those choices.  --A D Monroe III 17:15, 18 July 2005 (UTC)


 * I read DMR talking about this somewhere; if anyone wanted to track it down, a good place to start would be his Bell Labs webpage. As I recall the story is like this:


 * '&' used to be used for both logical and binary AND. And the same for '^' and '|'. After "&&" and "||" were introduced, they were sensibly given lower precedence than '&' and '|', but '&' and '|' were not moved up in precedence past the relational operators, since to do that would have broken several dozen programs where '&' and '|' were used as logical operators. (Quiet, heavy irony here.)


 * In short, it wasn't lack of understanding of operator precedence; DMR knew what would be the best thing to do, but didn't do it because he underestimated the future popularity of the language by about six orders of magnitude. DanielCristofani 05:57, 3 October 2005 (UTC)


 * The need for operator precedence is a symptom of an ambiguous syntax. [anon]


 * Perhaps so, but the lack of need for operator precedence is a symptom of a verbose syntax. Just look at Lisp. Sometimes a little ambiguity really isn't so bad. Deco 02:27, 19 November 2005 (UTC)

Conditional operator syntax
While syntax readability is necessarily a subjective matter, I'm afraid I must disagree with singling out the ternary conditional operator ?: as a bad example. In many functional languages such as Lisp and ML, this is the only type of conditional available (usually with a somewhat difference syntax), and it can often greatly reduce redundancy. The problem is that C programmers are unfamiliar with it and don't format code that uses it in a readable way. For example, here's some imperative code:

if (x > a) { if (y > b) { z = x + y;    } else { z = x - y;    } } else { if (y > b) { z = -x + y;    } else { z = -x - y;    } }

Now if we write this on one line with ?:, the result is fairly horrific:

z = (x > a ? (y > b ? x + y : x - y) : (y > b ? -x + y : -x - y));

If we format it a bit differently, however, it's really surprisingly similar to the original code:

z = (x > a ?        (y > b ? x + y        : x - y        )     :         (y > b ? -x + y        : -x - y        )     );

Punctuation is still uglier than words, but anyone could read this. In short, I think the lack of readability of this operator arises more out of conventional formatting of C than a language problem. Deco 07:22, 2 August 2005 (UTC)


 * I think it's excessively opaque. I would prefer the first (without curly braces) rather than the latter. ?: is fine when used judiciously; inappropriate use can make things look a mess. Dysprosia 08:05, 2 August 2005 (UTC)


 * Well, besides the fact that Jim Greenlee (I presume you know him, Deco?) would have my head for inventing a mythical ?= operator and calling it the ternary operator, one could argue that the language makes it too easy to abuse. C++, for example, has in some cases intentionally uglified certain constructs (such as casts) to discourage their wanton use and abuse.  Perhaps there should be a "pitfalls" section where the ternary operator can reside with goto?  Ataru August 2


 * It's ?:, not ?=. Something like ?= would imply it would be used in the sense that "a ?= b" is equivalent to "a = a ? b". Dysprosia 12:00, 2 August 2005 (UTC)


 * Maybe - I admit that ?: is often abused, much as goto can be abused. One could say that common language use problems are something worth mentioning about the language. I would generally avoid ?: as a matter of convention, and it's also cumbersome for simulating long if-else chains. Oh, and yes, Jim Greenlee would have your head indeed. :-) Deco 16:46, 2 August 2005 (UTC)


 * Where it comes useful is in implementing something simple like an absolute value function. Instead of having to use a long if-else, one can simply say int abs(int i) { return ( i > 0 )? i : -i ; } or something like that. Dysprosia 22:21, 2 August 2005 (UTC)


 * I wouldn't overstate its brevity; just writing "if (i > 0) return i; else return -i;" on one line isn't that much longer (formatting can clarify or make brief either one). Its primary semantic benefit is that it's an expression, and so it can be used to eliminate temporary variables and to yield return values from complex macros. In any case I would still contend that with proper formatting it's no more prone to excessive visual complexity than if-else (Lisp is worse, really). Deco 06:34, 3 August 2005 (UTC)


 * Discipline, Deco! I consider it good practice not to put ifs all on one line ;) Dysprosia 09:24, 3 August 2005 (UTC)
 * Yeah, I normally wouldn't, if only so I can step a debugger through it. Sometimes I'll write it on two lines with the "return" keywords lined up, but usually use at least 4. It is an unfortunate disadvantage of ?: that debuggers aren't typically able to step into portions of these expressions. Deco 19:25, 3 August 2005 (UTC)


 * The "(Lisp is worse, really.)" comment is a matter of opinion. Also, since Lisp is almost universally garbage-collected,
 * there is no need to worry about temporary variables.
 * Sorry, I wasn't asserting that Lisp is worse than C, just that its syntax is more verbose, which I don't think any Lisper could disagree with. Deco 02:30, 19 November 2005 (UTC)


 * Your code example seems to suggest another version, which is only possible using the ternary operator -  --68.58.69.117 18:24, 3 January 2006 (UTC) (Random832, not logged in))

Intermediate language wording
For the unnamed user editing the intermediate language section, why not go ahead and try rewording the first sentence or two in the section as well. Perhaps break the sentences up a little more and rewording phrases like "which then outputs finished object or machine code". Laundrypowder 20:44, 16 August 2005 (UTC)

C99 features
The reasoning behind current Visual Studio C99 support might as well be added. As seen on this transcripts http://msdn.microsoft.com/chats/transcripts/vstudio/vstudio_022703.aspx:

Q: Follow-up on the C99 "varargs" question, what, if anything, from C99 will we see in the future from VC

A: In general, we have seen little demand for many C99 features. Some features have more demand than others, and we will consider them in future releases provided they are compatible with C++. It is more likely we'll entertain C99 features if they are picked up in the next version of the C++ standard.

The phrase on their compilers could be worded a little more informatively as they consider new Visual C++ versions really only a c++ compiler. Laundrypowder 14:37, 25 August 2005 (UTC)

Hello, world
A lot of security holes result in the wrong usage of printf to output strings. Why the hell would someone believe  to be useful code, if not for all the misleading example code, which demonstrates that printf outputs strings.

An example should use functions in the way that they are meant to be used. Examples should not just happen to work for that special case.

Therefore I argue that  is to be replaced by   or   -- Hokanomono 15:40, 21 September 2005 (UTC)


 * printf("some string") is perfectly fine C code. It's idiomatic and has been in C examples at least since the Old Testament. I have no idea how this could cause a serious security problem (mismatch between format string and arguments might cause a problem. sprintf might cause a problem. scanf might cause a problem. But plain printf?). About the only reason that puts might be preferable is efficiency, which only plays a role in very exotic circumstances. The "Hello, world" example with printf is straight from K&R2, the standard C introduction. --Stephan Schulz 16:03, 21 September 2005 (UTC)


 * I agree with Hokanomono here. Instances of printf("I ignorantly use %s here.") and printf(string_from_network) are real problems. Examples stick to a beginner's mind and they try to expand from them. I suggest puts("hello, world") if we don't go into explaining format strings here. ANSI C and POSIX.1 have puts so it's standard. --TuukkaH 17:09, 21 September 2005 (UTC)


 * But the purpose of Wikipedia is not to teach bullet-proof coding practices, but to explain what C is. I claim that printf is a much more useful feature than puts, and, in existing code, much more used even with constant, zero-argument format strings. So it illustrates the existing language better.--Stephan Schulz 19:20, 21 September 2005 (UTC)


 * Further, the purpose of Wikipedia is not to teach useful features such as printf :-) puts illustrates the language well, although perhaps not the prevailing usage. We have to agree that we're talking about an example which tries to illustrate what simple C looks like. C is not the tool of choice for string processing. If printf is kept, I hope the shortcomings are pointed out at least. --TuukkaH 21:15, 21 September 2005 (UTC)


 * "printf" typifies C, "puts" does not. As noted, the example is from K&R!  If K&R changes, we must match it, but not before.  --A D Monroe III 01:38, 22 September 2005 (UTC)


 * Only the first example is from K&R, I agree that it should be presented in original form. However, there is a modern example following K&R's that should be the subject to our discussion. – Hokanomono 06:55, 22 September 2005 (UTC)


 * Which example? The second Hello-World closely follows K&R2 (except fot the added return). I think both should agree. I have no strong opinion on further examples (which probably means I'm a traditionalist and all my arguments are a rationalization ;-)--Stephan Schulz 08:34, 22 September 2005 (UTC)


 * This is all much ado about nothing. True, printf("I ignorantly use %s here.") and printf(string_from_network) are real problems.  But this is no reason to abandon printf entirely!  Similarly, i=i++ is a problem, but this does not mean that we abandon the extremely useful ++ operator.  Similarly, sqrt(-1) is a problem, but this does not mean that we ditto.  You solve these problems by teaching people about them so that they can learn to use the language correctly and appropriately, not by castrating the language so that it's somehow "safe".  This is, after, all, C we're talking about here, not Pascal! Steve Summit (talk) 01:00, 11 December 2005 (UTC)

Notes (by 68.199.16.197)
Someone has been adding a number of "Notes" to the article. While they seem well-intended, they are somewhat unclear and at least partially incorrect. I also think they don't belong into an encyclopedia as such - any useful information should go into the main text. I tend towards just removing most of them - any opinions? Here are mine: --Stephan Schulz 21:34, 27 September 2005 (UTC)
 * malloc and calloc: True but irrelevant. It is easy to avoid uninitialized memory, but it still is a frequent error. And there are good reasons to prefer malloc in many cases.
 * Modern garbage collectors do not add "tremendous overhead" to either runtime or (non-trivial) program code - indeed, they are often faster than explicit memory handling (Note: I'm a fan of explicit memory handling...;-).
 * Pointer casting: This is plain wrong. void* pointers can be cast implicitely. This is not C++.
 * Opaque structures: True, but it still is harder (or at least less convenient) than in OO languages with private members.
 * I agree that they should be removed. Even if correct, they probably should have been in parenthesis rather than as a note. wrp103 (Bill Pringle)  - Talk 14:23, 28 September 2005 (UTC)
 * I also agree to these corrections. I'm sorry that they slipped by me. I do recall that I was the one who first asserted that opaque structures are difficult to implement in C. (perhaps my original wording was too strong) Deco 02:35, 19 November 2005 (UTC)

ISO copyright concerns
The C standard document on http://www.nirvani.net/docs/ansi_c.pdf may constitute unlicensed distribution of a copyrighted work. This document must typically be obtained from ISO for 340 CHF (quite a lot of money if you think about it) and under a restrictive license. It may be a freely licensed pre-standard document, too, but I have removed the link for now since it's better to err on the safe side. Aragorn2 19:19, 22 November 2005 (UTC)
 * As far as I know the real C standard is not available for purchase in .pdf format. Also, you can get a copy of the C standard much more cheaply by purchasing the book The Annotated C Standard (ISBN 0078819520). Just don't read the annotations - they're pretty terrible. Deco 19:05, 8 December 2005 (UTC)
 * In fact you can purchase the up-to-date ("C99") ANSI/ISO C Standard, in PDF format, for $18 from the online store at www.ansi.org.
 * (The Annotated C Standard book, however, is for C90.) Steve Summit (talk) 00:53, 11 December 2005 (UTC)

Returns an integral?
"This line terminates the execution of the main function and causes it to return the integral value 0." Isn't it an integer, and not an integral that is returned? I'm not a nativ english speaker, but in norwegian an integral is a diffrent mathematical method (reversed derivation). I'm changing it so change it back if it's wrong ...
 * Here, "integral" is being used as an adjective, not a noun. The adjective "integral" has several meanings, but one is "having the property of being an integer". Deco 18:58, 8 December 2005 (UTC)
 * Thank your for the enlightenment, sorry for screwing up your article :)

notes on rewrite of Types section
I just made several significant changes to the Types section. Since the old text had been there for a while (and presumably accepted), I'd probably better explain my changes here, in case anyone has questions: Steve Summit (talk) 02:32, 11 December 2005 (UTC)
 * Saying that a pointer is a "complex type" at compile time, or is nothing but a raw memory address at run time, are both misleading. Some C systems implement "smart pointers" which carry around e.g.  bounds-checking information; these can be made completely compatible with the language definition.
 * The statement "Unlike many other languages, C typically represents arrays just as it does pointers" is simply false. Arrays are not pointers and are not "represented as" pointers; the "memory address" and "associated type" of an array are perfectly analogous to the address and type of a single, ordinary variable.
 * I deleted "reveal confidential data" from the list of potential consequences of array bounds violations, since if this is a possibility, it means you have serious problems at the OS level, far beyond any limitations of the C language.
 * C does not formally have multidimensional arrays; I thought this was discussed to death under "confusion about arrays" above.
 * No one "treats a double-precision value as an integer" in "low-level systems programming". Programmers in all sorts of applications often have to convert back and forth between integers and floating-point quantities; this is straightforward (and doesn't even require a cast).  What's tricky (and more "low-level") is to interpret the bits of a value as if they had some other type, but without converting them.  You can't use a simple cast for that!  (Though you might use a cast as part of the more complicated pointer expression you were using as part of the low-level bit inspection).

Is malloc the only dynamic memory allocator?
As far as I know, functions such as calloc, realloc also count. So, I changed the line "blocks of memory of any desired size can be requested at run-time using the library function malloc" to "blocks of memory of any desired size can be requested at run-time using library functions such as malloc"


 * No, but it is the standard memory allocator (iirc). Dysprosia 11:09, 29 December 2005 (UTC)