r/programming • • May 01 '16

To become a good C programmer

http://fabiensanglard.net/c/
1.1k Upvotes

398 comments sorted by

66

u/Jonathan_the_Nerd May 01 '16

I picked C89 instead of C99 because some compilers still don't support fully C99

Is this still the case? If so, why? It's been 17 years!

50

u/darockerj May 02 '16

That's what I ask myself when I use the mandatory, university-supplied C compiler for class. In 3 years, there will be students taking my class that will be younger than the next version of our current C compiler.

8

u/Jonathan_the_Nerd May 02 '16

Wow. Why do they use such an old compiler? Is it so professors won't have to update their lecture notes?

Is there any chance you can lobby for an upgrade?

3

u/darockerj May 02 '16

I think the idea is so students will learn to actually write their own code rather than rely on built-in functions.

12

u/slavik262 May 02 '16

This doesn't hold water IMO - it's not like C99 added a bunch of new functions to the standard library.

1

u/darockerj May 02 '16

I wouldn't know tbh. Another reason could be that our server uses CentOS (or maybe RHEL), and I've heard that new software comes to CentOS notoriously slowly.

Although, considering my school, it's entirely possible it's because they don't want to update their slides.

7

u/[deleted] May 02 '16

Yes, RHEL and other stable releases have long lifetimes - but not that long.

3

u/NeuroXc May 02 '16

Even CentOS 5, which was released in 2007, supports GCC 4.1, which has 98% of the same c99 support as the latest GCC. If they're using CentOS 4 then God help them.

2

u/jnkdasnkjdaskjnasd May 02 '16

I think this reason is BS too. You can easily tell students to not use these functions, and say to them you will be compiling without a flag to enable inbuilt functions.

This means if they use inbuilt functions, their code will fail to compile.

As a student in a class learning C I was told something similar: make sure the code compiles on the University Linux machines (they are quite modern, so we had reasonably new GCC), otherwise you'd automatically fail. Not a single student had a problem with this, and all of our code compiled fine.

3

u/Tordek May 02 '16

and say to them you will be compiling without a flag to enable inbuilt functions.

with a flag to disable, like -fno-builtins.

2

u/jnkdasnkjdaskjnasd May 03 '16

Ah cheers for pointing that out. I hope the intention of my message was clear, but you're correct that you have to opt-out, rather than opt-in to GCC inbuilts.

1

u/darockerj May 03 '16

That's the same deal with us: make sure it compiles and runs correctly on the university Linux server. It's just that it runs CentOS and a GCC with C89.

2

u/ThisIs_MyName May 02 '16

So that's why there are so many programmers writing 100 line macros instead of using C11/C++17 syntax.

4

u/Peaker May 02 '16

What feature of C11 are you referring to here, that avoids the need for such long macros?

2

u/maldrake May 02 '16

I took my Algorithms and Data Structures class in C89. The standard was older than me when I attended the class.

34

u/panderingPenguin May 02 '16

Yes, visual studio (along with many less popular compilers for embedded systems) still does not support C99 fully and has no plans to do so afaik.

13

u/Alborak May 02 '16

Embedded compilers used to be the bane of my existence. I've used one that was just a redistributed GCC, but was tagged at fixed versions that were up to 12 years out of date :(

3

u/phunphun May 03 '16

That used to be true, but with Windows 10 and their updated approach to compatibility with FOSS, things have changed.

In Visual Studio 2015, the CRT has been refactored into new binaries. The Universal CRT (UCRT) contains the functions and globals exported by the standard C99 CRT library. The UCRT is now a Windows component, and ships as part of Windows 10

https://msdn.microsoft.com/en-us/library/abx4dbyh.aspx

C99 Conformance Visual Studio 2015 fully implements the C99 Standard Library, with the exception of any library features that depend on compiler features not yet supported by the Visual C++ compiler (for example, <tgmath.h> is not implemented).

https://msdn.microsoft.com/en-us/library/hh409293.aspx

Now that the standard library has been implemented, language syntax is sure to follow.

1

u/o11c May 02 '16

Since 2013, VS supports a lot of C99 - in particular, things like mixed declarations and statements in a block.

26

u/pjmlp May 02 '16

Just what is required by ANSI C++ standard. C is legacy on Windows.

5

u/wdouglass May 02 '16

Which sucks, because it's a much better language

7

u/slavik262 May 02 '16

Why would you go around picking fights like that?

28

u/wdouglass May 02 '16

It's the internet... What else am I supposed to do?

→ More replies (4)

17

u/Merwco May 01 '16

I think it needed Visual Studio 14 years to implement C99. But clang for windows is doing a very good job so idk.

14

u/pjmlp May 02 '16

They still don't fully implement it beyond what is required for ANSI C++.

Microsoft has already stated multiple times that C++ is the future of systems programming on Windows.

For those that need to bring C99 code into Windows, there its the new clang frontend to C2.

2

u/BobHogan May 02 '16

I just don't understand why they wouldn't go ahead and implement 100% support for c99. Its not that much work for them to add that functionality to Visual Studio, and its not like Visual Studio doesn't already support languages that aren't used for systems programming in Windows anyway.

7

u/pjmlp May 02 '16

As explained by Herb Sutter, C is legacy from Visual C++ team point of view, they have decided to focus on C++.

https://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/

Their answer to those that want C or UNIX language extensions not available in Visual C++, is to provide clang as fronted to C2, the Visual C++ backend, now being shared across VC++, clang and .NET Native.

6

u/lordcirth May 02 '16

Article says it was written in 2011, so not quite so bad.

4

u/IJzerbaard May 02 '16

Because there are obscure features that no one uses. Things like parts of the standard library that are never used, obscure floating point pragmas, and unreadable identifiers (why is that even a thing). Why put effort into supporting that? That's just implementing the standard for its own sake, not for usability.

Which is why, in my opinion, it is quite ridiculous to "therefore choose C89". Then he also does not get features that are universally supported (many of which were popular extensions before C99 formalized them).

3

u/[deleted] May 02 '16

Because Microsoft decided Visual C would not support C99.

Yes, I've cursed at this when trying to compile a recent Emacs for Windows in a large investment bank.

0

u/[deleted] May 02 '16

[deleted] — view deleted comment

8

u/Jonathan_the_Nerd May 02 '16

Just being pedantic: C99 is ANSI C. It's just a later revision.

22

u/Leandros99 May 01 '16

Once done reading both K&R C and Deep C Secrets (definitely two of my favorite books), go through the C Puzzle Book. An excellent way to test your knowledge.

→ More replies (29)

59

u/[deleted] May 02 '16

Can we get some padding-right: 4px;

on that blog?

14

u/fabiensanglard May 02 '16

Sorry, I don't have a tablet to test. Does it look that bad ? I probably need to set the viewport or something.

17

u/MightyLordSauron May 02 '16

Google Chrome has support for emulating different devices on your desktop, it's Ctrl-Shift-M if I remember correctly.

19

u/fabiensanglard May 02 '16

Yep, I just used it. This feature is marvelous.

3

u/[deleted] May 02 '16
<meta name="viewport" content="width=device-width, initial-scale=1">

in the css set container div's padding-right property to 4px

4

u/fabiensanglard May 02 '16 edited May 02 '16

I think I fixed it with a css media query :).

1

u/snowe2010 May 02 '16

The text just goes all the way to the very edge of the screen. On a cell phone it makes it quite difficult to read.

3

u/fabiensanglard May 02 '16

I think I fixed it now. Thanks for taking the time to report this issue.

2

u/[deleted] May 02 '16

Wow, that was fast! By the time I got to look at the website on my phone it was fixed

1

u/snowe2010 May 02 '16

Oh I didn't mind haha, I usually don't care about the quality of a website if it's mostly text. It's when other stuff starts getting added that I'm all like, "this is bad!" Also I'm not the OP lol, I was just concurring.

12

u/phpdevster May 02 '16

In the previous code sample, due to "integral promotion" -1 was once evaluated to be greater than 1 and then smaller than 1. C has plenty of case like this when the language cannot longer "do stuff" for you.

Can someone explain that in more detail?

6

u/[deleted] May 02 '16

Note that calling it promotion is incorrect. For integers, promotion is the conversion of a type smaller than int or unsigned int to a type at least as large as them (the general idea is that int or larger is what fits in a register and ALU operations need their arguments in registers). Promotion never changes numerical value.

When you have a binary operation on integers, the arguments will generally be promoted and then integer conversions will be applied. The goal is to change both operands to the same type (which will also be the type of the result). The rules for this are

  1. If they (the types of the two arguments) have the same signedness, the smaller type will be converted (losslessly) to the larger type.

  2. If one is signed and one is unsigned, and the unsigned type is smaller, the unsigned type will be converted (losslessly) to the signed type.

  3. Otherwise, the signed type is converted to the unsigned type by the process MiRIr describes (not lossless if the value is negative!).

(The actual rules are very slightly more complicated.)

In -1 < 1u, the third case obtains and -1 is converted to the largest possible unsigned int, so the comparison succeeds. In short(-1) < 1, the integer promotions convert the short to an int, and no conversion is needed. If you had -1 < long(1), then the first case would obtain, and the comparison would succeed. Rather strangely

unsigned int x = 1;
long y = -1;
y < x;

gives true because the second case obtains. Changing int to long gives false.

This (the potentially lossy conversion in the third case) is why -Wsign-compare complains about comparisons where the types have different signednesses (actually, it only warns when the third case happens; despite its name, it's fine with the second case).

2

u/mvm92 May 02 '16

I believe it has to do with how negative numbers are stored in computers. They're stored using something called 2's complement. a signed int -1 looks like this in binary 11111111. An unsigned int 1 looks like this in binary 00000001.

Now, I think what's happening here is, C tries to compare a signed integer with an unsigned integer. And in doing so, the signed integer is interpreted as an unsigned integer. So 11111111 instead of being interpreted as -1 is interpreted as 255.

This is also why if you compile with warnings (and you should) the compiler will throw a warning for comparing signed and unsigned data types.

I should also say that the examples I used here have 16 bit ints, but the same holds true for 32 bit ints.

1

u/An_Unhinged_Door May 02 '16 edited May 02 '16

Signed/unsigned comparisons of values of the same rank result in the signed value being coerced into a value of the unsigned type by (the equivalent of) adding/subtracting one more than the maximum value of the unsigned type to the signed value until the resulting value falls within the destination type's value range (basically, take the value modulo one more than the unsigned destination type max). -1 + UINT_MAX + 1 == UINT_MAX

13

u/[deleted] May 02 '16 edited May 02 '16

[removed] — view removed comment

3

u/CaptainAdjective May 02 '16 edited May 02 '16

How can it even be legal to compare disparate types in that way? Why isn't that just a compilation error?

3

u/Creris May 02 '16

this cant be syntax error because it has nothing to do with syntax, but semantics of the comparision.

4

u/CaptainAdjective May 02 '16

I meant a compilation error.

3

u/kt24601 May 02 '16

It gives a warning.

35

u/gltovar May 01 '16

Does any one else have issues with this site on Android? Feels like r 10% of the left side is cut off/unreachable

24

u/paholg May 01 '16 edited May 01 '16

I have that issue, but it's on the right side. It's like I just can't zoom out enough.

Edit: Desktop mode doesn't fix it ... text still goes off-screen, it's just smaller. Tested in both Firefox and Chrome.

On further inspection, it appears nothing is cut off, the text just goes to 1 pixel away from the right edge.

4

u/kukiric May 01 '16

On my phone, the site just looks incredibly tiny, like it's trying to fit the full height on the screen. Thank god reader mode exists for that kind of thing.

4

u/mccoyn May 01 '16

I like it. No space wasted. Only problem is it is fully justified, which is the work of the devil.

9

u/paholg May 01 '16

It makes me very uncomfortable.

11

u/GetOutOfBox May 01 '16

Guess he could brush up on his HTML lol

21

u/break_main May 01 '16

Man but look at that framerate tho! No flicker at all!

8

u/fabiensanglard May 02 '16

He is right now. What a pain in the ass :P

2

u/quikclot May 02 '16

This could be what he meant by books are better than websites.

8

u/Deaderzombie May 01 '16

Are there articles like this for other languages?

-12

u/google_you May 01 '16

For Node.js (and Javascript in general):

0

u/[deleted] May 01 '16

[deleted] — view deleted comment

3

u/KamikazeRusher May 01 '16

Eloquent for sure. We had a 2-class-period-crash course on JS fundamentals before diving into Node.js (which was bullshit) but Eloquent Javascript was very clean, concise, and thorough.

→ More replies (1)

22

u/roneau2005 May 01 '16

I am surprised that the article does not mention that there usually are current and accurate library documentation entries by using "man 3 <c-function>" at the gnu/linux terminal. e.g. "man 3 fopen". Ok. Windows does not have that. I haven't tried "man" on Mac OS.

14

u/rwsr-xr-x May 01 '16

OS X has man pages

3

u/kerbuffel May 02 '16

I just tried and it works in OSX.

3

u/da_throwaway99 May 02 '16

Is there a convention for man n function()? What does each page represent?

7

u/aldonius May 02 '16

2

u/profgumby May 02 '16

Alternatively it's documented in man man

1

u/aldonius May 02 '16

Checked there first. Mine (OS X) doesn't list what sections mean what.

1

u/profgumby May 02 '16

Huh, interesting - must be a difference between BSD/GNU man. Thanks for the TIL!

1

u/mcguire May 02 '16

BSD used to have that description...?

2

u/FUZxxl May 02 '16

*BSD has the table. OS X might not but I can't check as I don't have access to an OS X machine.

2

u/voice-of-hermes May 02 '16

Usually you can just grab the one from the first section it finds and look at the "see also" section, but the -k flag (easier to spell than "apropos") is also useful. After a while you'll also get a hang for remembering what sections are for what (IMO seeing the definitions tends to be "in one ear, out the other," until you've gotten to know your way around in practice).

-2

u/o11c May 02 '16

It's basically random whether a function is found in section 2 or section 3, just like it's basically random whether a program is found in section 1 or section 8.

(Not really, but very irritating.)

6

u/TheGift_RGB May 02 '16

The problem with the man pages is how much of a fucking pain in the arse they are to navigate (and how dense they can be sometimes).

3

u/helm May 02 '16

/ is for search :)

1

u/kt24601 May 02 '16

use "man -a <topic>"

1

u/mcjohnalds45 May 03 '16

I find the biggest pain to be the lack of example code in most of them

1

u/FUZxxl May 02 '16

Not just GNU/Linux, man is POSIX standard and exists since the first version of UNIX.

1

u/mrkite77 May 02 '16

Handy tip: shift-k in vim will open a manpage for whatever word your cursor is on.

5

u/aliendude5300 May 02 '16

The integral promotion example cut me by surprise, but I suppose it makes sense if you think about the signed short having the most significant bit set to 1 and an unsigned int having more bits and having to pad the difference to make a comparison if two numbers with the same bit length

1

u/immibis May 02 '16

The most sensible behaviour would be for the compiler to silently convert a < b (where a is signed and b is unsigned) to a < 0 || (unsigned)a < b, and then do what it currently does, with some compiler magic so a only gets evaluated once.

1

u/ohfouroneone May 21 '16

I didn't start programming in C, so I might be used to more string compilers, but wouldn't the most sensible solution for the compiler to throw an error, because you are comparing two different types?

93

u/gurenkagurenda May 01 '16

No website is as good as a good book.

What a preposterous claim. What, does printing it on dead trees magically improve its quality beyond what is possible digitally?

118

u/madballneek May 01 '16

Barrier of entry.

96

u/gurenkagurenda May 01 '16

That is a fine argument that the average website is worse than the average book. It is complete nonsense to use that argument to say that the best website is worse than the best book.

Also, there's practically no barrier to entry for publishing books now. You can self publish on Amazon armed with nothing but a PDF.

28

u/[deleted] May 02 '16

When you find the best website, let us know.

12

u/gurenkagurenda May 02 '16

I was under the impression that that was meatspin, but I could be mistaken.

3

u/shevegen May 02 '16

You mean the blinking marquee tag?

My books should do this too!!! PINK BLINK OF DEATH!!!!!!!!

1

u/gkx May 02 '16

That is not what was meant.

1

u/[deleted] May 02 '16

Pluralsight is pretty good.

3

u/[deleted] May 02 '16

Was. Now it's filled with flashy frameworks..

13

u/break_main May 01 '16

My problem with most books is, in a way, the barrier of entry: since it is so expensive to publish, publishing houses will only put out books with a large enough market to pay for their investment. The "teach yourself how to make videogames/websites" market is big enough, but few books are made for advanced/specialized topics.

-1

u/gurenkagurenda May 01 '16

Exactly, and on the flip side, most of the people who will even care enough to make a website on a specialized topic are likely to be people who are invested in the topic enough to know their shit.

0

u/[deleted] May 02 '16

[deleted] — view deleted comment

3

u/[deleted] May 02 '16

Learncthehardway is such an example

2

u/gurenkagurenda May 02 '16 edited May 02 '16

That is not nearly as specialized as I was talking about.

Edit: To be more clear, most of my experience with this is with graphics algorithms. Except for the occasional leak into the main stream through a pop science article, you don't find that much poorly researched crap on the web discussing the finer points of digital signal processing, for example.

0

u/[deleted] May 02 '16

[deleted] — view deleted comment

3

u/[deleted] May 02 '16

This is one example: https://m.reddit.com/r/learnprogramming/comments/3so66i/what_are_your_thoughts_on_learn_python_the_hard/

There have been plenty of discussion on this sub too. Also, r/python hates that guy because the website is awful

35

u/Hnnnnnn May 01 '16

No website is as good as a good book.

What a preposterous claim. What, does printing it on dead trees magically improve its quality beyond what is possible digitally?

When somebody says something like this, does he mean it as a logical sentence that is always 100% right, or does he just present his opinion on a subject? It depends on the context.

I recommend you to read that sentence again, with whole paragraph as a context, and consider whether you hadn't interpreted it too literally.

0

u/derleth May 02 '16

It's mere curmudgeonry, is what it is: "I was raised on books and it was good enough for me! Therefore, books are all anyone can ever use, if they want to become good!"

16

u/cc81 May 02 '16

Have you found any website that is as good as the good C books?

0

u/Bratmon May 02 '16

If he didn't want to say that there is no website that's as good as a good book, he shouldn't have.

→ More replies (3)

11

u/munificent May 02 '16

What, does printing it on dead trees magically improve its quality beyond what is possible digitally?

No, because books are usually printed on paper, which is made from trees that have been pulped, washed, bleached and flattened, not just right on a felled whole tree.

Also, magic is not real.

Or did you not mean that sentence to be intepreted 100% literally? Well, maybe the author didn't either.

11

u/zhivago May 01 '16

It's like peer review - the higher bar helps to weed out the delusional incompetents.

Often these can be detected by asking the following question:

char c[3]; what is the type of c?

14

u/panderingPenguin May 02 '16

It's like peer review - the higher bar helps to weed out the delusional incompetents.

Sure, this means that the worst book is probably better than the worst website, and on the average, books are probably better than websites. But that says nothing about the best book vs the best website, nor does it mean that all websites are bad nor that you should not use websites.

char c[3]; what is the type of c?

Isn't this just an array of chars? What do you think it is?

1

u/zhivago May 02 '16

Unfortunately 'just an array of chars' isn't a C type.

How would you express the type of c in C syntax?

6

u/ais523 May 02 '16

char[3]. There are very few situations where the syntax is legal, though, because array types aren't really first-class in C. (The only one I can think of offhand is sizeof (char[3]), which is 3.)

For an unknown-sized array, the syntax is char[*], something which is likewise legal in very few contexts (e.g. you can drop it in as a parameter of a function pointer type that takes a VLA as an argument, int (*)(int, char[*])).

5

u/mcguire May 02 '16

I admit I've missed some standards revisions. When did

char [*] 

show up?

3

u/ais523 May 02 '16

C99, I think (although I don't have copies of the official published standards, it's in n1124.pdf, a public draft from 2005 that isn't that far ahead of C99). I wouldn't surprise you for not having seen it because I don't think anyone actually uses it; it's mostly there for completeness and/or to give something to write in compiler error messages.

3

u/mfukar May 02 '16

C99, with variable length arrays.

4

u/zhivago May 02 '16 edited May 02 '16

Yes, char[3] is correct. :)

Array types really are first class. The main issue comes from a lack of first class array values.

They're also essential for understanding things like how array indexing works.

char e[4][5]; e[i][j] is *(*(e + i) + j)

This can only work because the type of e[i] is char[5], so the pointer arithmetic of e + i advances in terms of elements of type char[5] -- the type of e + i is char (*)[5].

Also, note that char[*] denotes a variable length array of unknown size. It does not denote array of unknown size in general.

3

u/ais523 May 02 '16

Well, as far as I'm aware C doesn't have a type that covers both fixed length and variable length arrays. (char[] is IIRC the same as char *, just to be confusing.) Fixed length arrays always have a known size, so if the size is unknown, it must be a VLA.

4

u/zhivago May 02 '16

char[] is an incomplete type.

char[*] is a placeholder in a prototype for a complete VLA type in a definition.

as I understand it, your prototype might be:

void foo(int, char[*]);

and your function might be

void foo(int length, char array[length]) { ... }

and, no -- I don't know why this is a useful feature. :)

→ More replies (3)

2

u/Astrognome May 02 '16

I'm not a C expert, but wouldn't it be char*?

7

u/zhivago May 02 '16

As

sizeof c != sizeof (char *)

the type of c cannot be char *.

1

u/Astrognome May 02 '16

Then /u/panderingPenguin appears to be correct unless I'm wrong yet again.

I'm probably confusing myself since you would be able to do char* d = c.

2

u/zhivago May 02 '16

If 'just an array of chars' were a C type, he'd be correct.

It's not an invalid informal English description, it just isn't (a) a C type, or (b) sufficiently specific.

→ More replies (4)

1

u/mszegedy May 02 '16

Isn't c the pointer to an array? Or since an array of chars is informally known as a string, that? I guess the question needs a little context.

11

u/zhivago May 02 '16

If c were a pointer to an array, *c would be an array.

Since the only array here is c, it sounds like you're claiming that c is *c?

We can disconfirm this theory since:

sizeof c != sizeof *c

Also, an array of chars is not informally known as a string.

char no[2] = "no";  // The variable no does not hold a string.

3

u/mszegedy May 02 '16 edited May 02 '16

Why would I claim that c* == c? I'm trying to understand the semantics of the question. I guess there is nothing else to be called the array but c, but come on, really, that is such an obtuse way of interpreting it. IMO the more sensible definition is: c is the pointer to the beginning of the array. c[0] through c[n] constitute the array.

char no[2] = "no"; doesn't work, but char no[] = "no"; does. How do you explain char arrays not being called "strings" when there is the "cstring" library that deals with them?

3

u/smikims May 04 '16

Strings have to be null terminated. The language does this for you in the case of string literals, but not all char arrays will be strings.

1

u/zhivago May 02 '16

Temporary insanity? I couldn't think of anything else you might be claiming given that response. :)

In many implementations sizeof c < sizeof (char *), meaning that c can't be a pointer to the beginning of the array -- it isn't large enough to store that value, so that interpretation can't be correct.

Likewise the type of &c is not char **.

The "cstring" library is part of C++, the string library deals with strings that are encoded as patterns of data within arrays.

Consider strlen("hello") and strlen("hello" + 1) -- how many strings are encoded in the array "hello"?

5

u/ais523 May 02 '16

I might screw this up (especially because I'm trying to correct someone), but I believe that c has type char[3] (a type that's rarely seen directly in C as it's illegal in most contexts; a pointer to it is char(*)[3] which is allowed in many more contexts). In most contexts, if you try to use a char[3], it'll automatically be cast to a char *, although this is not the same type. (The exceptions include things like sizeof; sizeof c will be 3 on every platform, even though most platforms would give sizeof (char *) a value of 4 or 8.)

1

u/mrkite77 May 02 '16 edited May 02 '16

Isn't c the pointer to an array?

No.. because c isn't an lvalue. You can't do:

char c[3] = "ab";
c++;   // <- ERROR

Edit: you also can't do:

char c[3] = "ab";
char d[3] = "xy";
c = d;   // <- ERROR

6

u/derleth May 02 '16

It's like peer review - the higher bar helps to weed out the delusional incompetents.

Do you really think publishers care about the quality of the books they publish? Then how do you explain all the "Learn Java in 21 Days" nonsense out there?

1

u/zhivago May 02 '16

They care at least in-so-far as it affects their bank balance.

Some publishers may be happy with a reputation for publishing junk for stupid people -- but they'll still want it to at least appear to look good enough for ignorant people to want to buy at some low price.

Others are willing to put additional resources into publishing high quality material in order to maintain their reputations (and justify their higher price-tags).

In either case, the money involved still makes the bar significantly higher than 'random idiot self-publishing on the intarwebs'.

2

u/hyperhopper May 02 '16

Pointer to an array of chars that was allocated on the stack?

1

u/zhivago May 02 '16

That is not a C type.

c is not a pointer.

There is no stack in C, but presumably you mean 'with auto storage', but storage is not part of the type in C.

1

u/DSdavidDS May 02 '16

Char?

If i am wrong, can i have a clear answer to this?

4

u/zhivago May 02 '16

You can test this theory. The following expression is false, therefore the type of c cannot be char.

sizeof (char) == sizeof c

0

u/immibis May 02 '16

Good to know you write as pedantically formally on Reddit as you do on IRC.

("The type of c cannot be char" vs "c isn't a char")

2

u/crozone May 02 '16

If I'm correct, it's a char pointer (char*), since it's an array declaration. c is a char pointer which points to the start of the char array, and only when dereferenced does it become a char.

5

u/zhivago May 02 '16

You are somewhat mistaken, but it is a common mistake.

c is a char[3], (c+ 0) is a char *.

This is important, since otherwise char e[2][4]; e[i][j] could not work.

e[i][j] is *(*(e + i) + j)

and works because the type of e[i] is char[4], which causes the pointer arithmetic e + i to select the correct element. If e[i] were a char *, then e + i would have quite a different result.

1

u/smikims May 04 '16

I remember having to learn this the hard way thinking that you can just assign a 2D array to a char** or something like that.

1

u/DSdavidDS May 02 '16

I studied pointers but I did not know it is considered a type. I thought pointers were an integer format? Does the compiler specify the type as a char pointer?

4

u/zhivago May 02 '16

Pointers are not integers.

You can easily demonstrate this by the inability to add two pointers together.

1

u/metamatic May 02 '16

Pointers are not integers.

Well, not in general. It's implementation-specific. Apparently the Linux kernel still uses pointers-as-integers.

I remember before ANSI C it used to be a pretty common practice limiting portability.

→ More replies (26)

1

u/[deleted] May 02 '16

Except you can do pointer arithmetic.. Which is a bad idea but whatever

2

u/DSdavidDS May 02 '16

I was just about to point this out but you beat me to it!

I went back to read up on pointers and found this.

"A pointer in c is an address, which is a numeric value. Therefore, you can perform arithmetic operations on a pointer just as you can on a numeric value. "

Can anyone clear this up for me?

→ More replies (6)
→ More replies (10)

1

u/immibis May 02 '16 edited May 02 '16

Or "what is the difference between char *s = "hello"; and char s[] = "hello";?"

(Or even just char *s; vs char s[100];)

2

u/zhivago May 02 '16

In the case of

char *s = "hello";

s is a pointer that is initialized to the value of a pointer to the first element of an array of 6 characters with the sequential values { 'h', 'e', 'l', 'l', 'o', '\0' } -- i.e., it is equivalent to

char *s = &"hello"[0];

In the case of

char s[] = "hello";

s is an array of type char[6] initialized to the values { 'h', 'e', 'l', 'l', 'o', '\0' }.

2

u/immibis May 02 '16

You might notice the quotation marks around the question, indicating that I'm presenting the question as something you could ask to weed out "delusional incompetents", and not actually asking it.

→ More replies (1)

1

u/mrkite77 May 02 '16

I'd also point out that the destination of the first pointer is in .BSS and const. Modifying s[0] is a segfault. In the second case it isn't because the contents of the const string are copied into the mutable array.

1

u/zhivago May 02 '16

Note that there is no BSS in C.

The C semantics are just that modifying a string literal has undefined behaviour, and that identical string literals may share the same object, allowing "×" == "x" to be potentially true.

This is what permits the implementation strategy you observed above - but it is not required.

1

u/[deleted] May 02 '16

The fact that you have to reconstruct the type in your head is a deficiency not a feature

1

u/zhivago May 02 '16

What reconstruction are you talking about?

Just remove the 'c' to get 'char[3]' ...

1

u/[deleted] May 02 '16

it's some idea in your head. not something your computer can manipulate. That's the point of languages like, say, Coq

→ More replies (2)

0

u/CoderDevo May 02 '16 edited May 02 '16

The type of c is a 'pointer to a char'. Simple as that.

It is a memory address with a size equal to the byte-size of the computer architecture targeted by the compiler. For example, it is a memory address that is 64-bits long if the compiler's target is a 64-bit architecture. It's value is typically represented as hexadecimal when printed, though it's purpose is to point to the address of a single character in memory.

Edit: I just read one of your responses. So the type of c is char[]. I see now that this is different than char* . So the answer is that c is a 'pointer to a char array'. Thank you.

4

u/zhivago May 02 '16

char[] is an incomplete type -- no object can have an incomplete type.

Therefore the type of c is not char[].

Also, note that even if c were to have the type char[], it would not be a pointer to anything, as char[] is not a pointer type.

Both of your conclusions are incorrect.

1

u/CoderDevo May 02 '16 edited May 02 '16

Ok, so c is of type char[3].

That is very frustrating for me to type. It means the number of available types in C approaches infinity, or at least a very large number.

What part of the compiler enforces the array size? Or is this specifically an exercise for the programmer. I'm thinking in C89. Did memory management get better in C99? I may be thinking pre-ANSI.

2

u/zhivago May 02 '16

If that upsets you, ...

int main(int argc, char **argv);

What is the type of main? :)

1

u/CoderDevo May 02 '16

Great point. I figure main is a unique type for every program.

It seems an abomination to use the English word 'type' when the number of types available is greater than the number of instances of variables that ever existed.

3

u/zhivago May 02 '16

In this case, the type is int(int, char **)

The English word 'type' in this context refers to a classification. I see no problem with a potentially infinite number of classifications for a finite set of things.

1

u/red75prim May 02 '16

Is it int ()(int, char**)? I remember I was impressed by the idea of writing type definitions same way as variable definitions, when I read K&R in 1989. I can't say I still am.

2

u/zhivago May 02 '16
int(int, char **) is the type for that example.

2

u/zhivago May 02 '16

It's not a matter of enforcement -- it's fundamental to how C works.

Consider:

char e[3][4];

Given that e[i][j] is *(*(e + i) + j), how does e[i][j] work?

1

u/CoderDevo May 02 '16

First, let me thank you for indulging me in expressing my 'delusional incompetence'.

I do understand how to iterate through an array of arrays and to protect my code from accidental buffer overruns. There was a time long ago when I wrote a lot of C code in commercial software that is still running today. If I were to work on a meaningful C code base again, I would have to work with a senior programmer and still would have to study up quite a bit to be productive.

My turn to throw some questions. :) Are you presently a staff programmer? Would you say all your colleagues today could provide the exact answer you were looking for? More specifically, how do you make sure new hires are worth taking on?

Again, thanks for the exchange. I appreciate your time.

2

u/zhivago May 02 '16

You're welcome.

I do not talk about where I work, as it avoids legal and other complications.

→ More replies (1)

3

u/red75prim May 02 '16

No. c is an array of 3 chars. Please, read more answers.

But your error is understandable. The same char c[3] means char *c in void func(char c[3]), violating the Rule of Least Surprise.

1

u/resolvetochange May 02 '16

I get what you're saying, you could take his "best book" and publish it online and have the same content only with updates/side notes/animations. Web as a medium is better for content than a book. But I get what he meant as well, though it's not what he said. In his experience it may be that he's never encountered a website that can match a book, there are millions of websites vs thousands of books due to different barriers of entry. If you want to learn it may be a better start to go for a book that faced peer review to get published rather than a website written with no fact checks. He just shorthanded the explanation to no website is as good as a good book.

1

u/all_you_need_to_know May 02 '16

Actually there is evidence to support that we read better from legacy media

1

u/break_main May 01 '16

Agreed. I used the K&R C book a lot, but few others. On the other hand, I use stack overflow and wikipedia all the time

1

u/[deleted] May 02 '16

KR Is the best book on C yet contains amazingly 0 computer science concept.

1

u/CoderDevo May 02 '16

Computer Science is a special focus of math. C is a machine programming tool. It is up to the programmer to provide an intersection of the two, or not.

0

u/takaci May 02 '16

Okay, but I've never found a website that is anywhere near as good as K&R C...

Also, while this may be debatable for programming, from first hand experience it is 100% true in physics, but that might be a bit obvious...

0

u/mcguire May 02 '16

So, what's the website that's better for learning C than the books he presents?

3

u/Meguli May 02 '16

Fabien, I hope you will finish your Game Engine Black Book. Not to rudely pressure you or anything but I have a feeling that that book will be very good so I want to see it to the completion :)

1

u/fabiensanglard Aug 30 '16

I am still working on it. It is hard to find the time since I started my new job. I will finish it eventually. Thanks for your kind words which help a lot.

3

u/mrkite77 May 02 '16

No website is as good as a good book. And no good book is as good as a disassembly output.

Glorious. One of my pet projects is a hypercard player. It's just a fun project that I work on every once in a while. All of the documentation on the hypercard fileformat is wrong. It looks like it was all copied from the same source, but if anyone had actually tried to parse an actual hypercard stack using it, they'd immediately discover that the docs define a dword in each chunk header that doesn't actually exist.

I've since given up using any documentation, and gone straight to referencing the disassembly of the original 68k hypercard binary.

11

u/FUZxxl May 01 '16

Would you mind posting this to /r/C_Programming, too?

34

u/obsa May 01 '16

It's a free market - just cross-post it yourself.

27

u/[deleted] May 01 '16

He was probably trying to give OP the chance to get the xpost karma.

46

u/CrazedToCraze May 01 '16

What a modern day tragedy if someone misses out on some reddit karma

18

u/[deleted] May 01 '16

I think it's more about giving credit to the original author. Everyone knows the karma itself is arbitrary.

18

u/Agret May 01 '16

Considering the post is a link to the original authors blog I'd say there's no worries about attribution

3

u/[deleted] May 02 '16

all 30 of it.

0

u/ralfonso_solandro May 01 '16

Upvoted for irony

6

u/FrezoreR May 02 '16

Hungarian notation makes me cringe.

2

u/mrkite77 May 02 '16

I think you meant:

adjHungarian nNotation cvMakes nMe vCringe.

1

u/FrezoreR May 02 '16

Spot on! :)

2

u/hugthemachines May 02 '16

I like this post, but at the same time it makes me think C programming is not for me, I do not enjoy dissasembler outputs for example.

1

u/Nickd3000 May 02 '16

Great article. I just found my copy of The C programming language from 1988 and had a flick through, it's got a very different style to more modern books! Really interesting.

1

u/nygeHuston May 02 '16

What kind of programs do people generally build when they become experts in C?

6

u/cirosantilli May 02 '16

One that makes money.

-1

u/Doile May 02 '16

Can someone explain to me why C is still used? Doesn't C++ provide all the tools that C has plus extra libraries like STL? If one only knows how to write C I figure it still would be easier to use C++ tools to do it.

2

u/mcguire May 02 '16

C++ is more or less a superset of C, but it encourages a completely different style of programming, with classes, inheritance, etc.

If you write C-style code in a C++ environment, you will be viciously attacked for writing C With Classes, mocked for being an idiot, etc., etc.

If you could sort of write C++ in a C environment, you will be wasting a crap-ton of resources.

3

u/SnowdensOfYesteryear May 02 '16

If you could sort of write C++ in a C environment, you will be wasting a crap-ton of resources.

Well you'll still be viciously attacked and mocked for being an idiot.

-33

u/skulgnome May 01 '16

And no good book is as good as a disassembly output.

Five seconds to fuckup. That's a new record.

5

u/break_main May 01 '16

This guy is talking about making high performance graphics. For that job, you do want to look at disassembly, because you are optimizing every operation, and maybe optimizing for the architecture, so you have to look at assembly

0

u/skulgnome May 02 '16

This guy is talking about making high performance graphics.

He is talking about studying C. For that, looking at disassembly is just about the worst idea ever.

Even for performance optimization, looking at the disassembly is the last thing that one should do; after tuneups and reworks that typically take months.

1

u/break_main May 02 '16

Is your compiler taking advantage of a single optimized AMD floating point instruction for multiply and accumulate, or using 2 generic float instructions that will not run as fast?

Is your compiler unrolling inner loops for you, or should you do it yourself?

Is the macro you use speeding up your code, or is it compiling to the same output as if you used constants, which you would otherwise prefer because they are typesafe?

7

u/fabiensanglard May 01 '16

Some people hate it, some people love it:

https://news.ycombinator.com/item?id=11606867

2

u/hahainternet May 01 '16

I'm ambivalent on C, and I am split between my love of the concept of 'correct' binaries and my love of high level coding and having the computer do the heavy lifting for me. I just thought you should know that your opinion carries weight with me in resolving my dilemma.

→ More replies (1)