C coding guidelines

B

Bart

Same applies to main. But when we talk about "entry point" in C, we're
talking about the entry point into user code. For hosted C, that's
main. For freestanding implementations it needn't be main, and for
Win32 it's WinMain. Check Petzold.

main() also works for Win32/GDI. Obviously with different arrangements
for obtaining the command line.
Yes, but I'm talking specifically about Win32 GUI. Incidentally, I
don't know about you but the DLLs I write have multiple entry points,
which I like to call "library functions".

Don't they each also have a main() function?
 
F

Flash Gordon

Bart said:
main() also works for Win32/GDI. Obviously with different arrangements
for obtaining the command line.

That requires something other than the standard MS startup code for a
Windows GUI code, since the standard MS startup code calls a function
named WinMain.
Don't they each also have a main() function?

Why? A DLL is a library, so why would it have a main() function?
 
O

osmium

Boy, that takes me back. I bought a copy of Turbo C++ for Windows (Not to
be confused with Turbo C++) and fired it up. They claimed it met some
standards and I knew the standard had a "main". I studied and studied that
box to see if they had lied to me, but I never reached a definitive answer.
 
B

Bart

Why? A DLL is a library, so why would it have a main() function?

So it can initialise itself? But I think the function might be called
DllMain instead, and is called when first loading the library.
 
F

Flash Gordon

Bart said:
So it can initialise itself?

Ah, but not all DLLs require any initialisation.
But I think the function might be called
DllMain instead, and is called when first loading the library.

Well, that's not main() is it, it's DllMain.
 
B

Bart

In
<686ffa1e-8282-411e-988e-49c2ddd2f...@q35g2000vbi.googlegroups.com>,
My DLLs don't have a DllMain function either.

They're optional. But if you put one in, it should be called on
loading and freeing of the library, in theory (it didn't work when I
tried it just now, unless I called it LibMain).
 
G

Guest

| I should perhaps emphasise that I am not recommending Indian Hill
| unreservedly. It contains some style guidelines with which I
| disagree, and it should not be taken to be a sacred text that must be
| obeyed in all ways. That's why I mentioned the possibility of
| modification. The best members of your team should be free to make
| sensible modifications at the outset, and you should also institute a
| mechanism for considering later changes, although that mechanism
| should have enough inertia to allow for reasonable stability in the
| code base.

I found a LOT of stuff in there I disagree with. Of course, there is no
one perfect style. I don't even strictly follow my own style since there
are times exceptions should be made.

What can be useful for businesses and teams that need to make their code
more uniform is a structural template for coding style and rules. This
would reference all the various issues that should be considered, along
with examples of variations of solutions others have come up with.
 
T

Tech07

Richard said:
Same applies to main. But when we talk about "entry point" in C, we're
talking about the entry point into user code.

That's one definition, certainly "good enough" for most high-level coders.
Realize that if you use the /ENTRY switch with the MS linker you won't be
replacing the call to WinMain, but rather the REAL entry point, so standard
library initialization (and other things like static object constructor
calling) will not be done.
For hosted C, that's
main. For freestanding implementations it needn't be main, and for
Win32 it's WinMain. Check Petzold.

Just semantics though. I'm sitting right in front of a compiler telling me
what the entry point is for the console test program I'm working with:
mainCRTStartup.
Yes, but I'm talking specifically about Win32 GUI.

The REAL entry point for a Win32 GUI program is WinMainCRTStartup.
Incidentally, I
don't know about you but the DLLs I write have multiple entry points,
which I like to call "library functions".

I wouldn't call those entry points either: I'd call those "exported
functions". _DLLMainCRTStartup is the REAL entry point for a DLL.
 
G

Guest

| then how do people think about this one: http://www.kernel.org/doc/Documentation/CodingStyle

Tabs should be 8 characters because that's how they have been for ages.
Most display mechanisms that handle tabs work this way. However, there is
no basis for that to conclude that indentation of code must be 8. It can
be 8, and that makes files a bit smaller. Are small source files important?
I don't think so. Consistency is. Pick an indentation and use it uniformly.

I don't think 3 levels of indentation means you are screwed. And the limit
on 80 columns is completely outdated. I'm using a 142 column display. Any
that can't use at least 120 columns is still using old technology. Upgrade.
80 columns is for punch cards.

Interestingly, they use exactly the same "inconsistency" I use for placement
of brances (next line for functions, end of line for all else).

I do use a space after _operator_ keywords like sizeof. The reason for that
is that sizeof itself does not require parenthesis. You can put a variable
name without parenthesis right after sizeof and it is valid. Type keywords
do need parenthesis. When I have parenthesis around something to enclose,
I have a whitespace (it can be a tab where applicable) before the start.

I usually put spaces after unary operators. In many cases not doing so makes
them hard to read. In particular, the & symbol looks like a letter. I did
originate as a letter in Old English.

I like the naming strategy. Names with smaller scope of usage should be
shorter. Names with a wide scope of usage should be longer.

WhatIHateTheMostIsUsingCapitalizationAsSeparationAndJammingWordsTogether.

I like the typedef rules. Accessor functions/macros for struct members has
to be judged in terms of whether they are just defeating opacity, or provide
something useful. The former should be avoided.

I usually separate functions in one source file with TWO blank lines.

I use gotos for common error cleanup the same way.

I disagree on comments. I think they should explain HOW things work, too,
even if it is obvious (and it's good if it is obvious). Confirming that
the code is written as intended is good. I also do like the C99 // style
comments because in most cases I find them easier to read.

I might try their .emacs setup.

What they call CAPITALIZED is actually UPPER CASE. Capitalizing Just Makes
The First Letter Upper Case.

Years ago I got burned by gcc's mishandling of inline functions and started
to use macros instead. I got good with macros. But I guess I should move
at least some of them back to inline functions, as it appears that gcc has
resolved the issues. But this is when inline is good usage. There is a lot
of cases where it is not, as this document points out.

BTW, that mishandling was a size limitation that was way too small. I have
heard that since gcc 4, this is fixed. I'll try that some day.
 
G

Guest

| In Indian Education system, in Punjab School Education Board (where I
| did my graduation) or Kurukshetra University from where my friend did
| his Masters or in around 10 Engg. colleges from where my other friends
| (old classmates) did their Bachelors of Technology and Bachelors of
| Engineering, at *all* of those places me and they were taught to write
| void main(). It was CLC who taught me, very first time in my life, to
| use int main(void). No, I am not moaning about it (I moan about it on
| my blog).

I do not think India has a monopoly on bad teaching. I've seen lost of it
all over. The specifics might vary.


| I am just trying to tell you in Indian schools (as of 2009) teachers
| teach their students to write void main() and they recommend the books
| who use void main() or other stupid things. Herbert Schildt was one of
| the popular authors to learn from during my graduation. My teachers
| told me that he was the best selling author on C and C++ and Wikipedia
| conforms that.

Best selling != best. A friend of mine, whom I taught C programming to,
actually lived across the street from Herbert Schildt in Mahomet, IL for
a while. The stories I've heard cannot be repeated online.

Google can show you many long documents of errata in his books.
 
K

Keith Thompson

Tabs should be 8 characters because that's how they have been for ages.
Most display mechanisms that handle tabs work this way. However, there is
no basis for that to conclude that indentation of code must be 8. It can
be 8, and that makes files a bit smaller. Are small source files important?
I don't think so. Consistency is. Pick an indentation and use it uniformly.
[...]

My own opinion is that (a) tabstops should be 8 columns, and (b)
tabs should not be used in source code, only spaces.
 
J

James Kuyper

| who use void main() or other stupid things. Herbert Schildt was one of
| the popular authors to learn from during my graduation. My teachers
| told me that he was the best selling author on C and C++ and Wikipedia
| conforms that.

Best selling != best. A friend of mine, whom I taught C programming to,
actually lived across the street from Herbert Schildt in Mahomet, IL for
a while. The stories I've heard cannot be repeated online.

Stories from a neighbor that "cannot be repeated online" sound unlikely
to be relevant to his competence (or lack thereof) as a author of C
programming books. Are they?
 
R

Rich Webb

Tabs should be 8 characters because that's how they have been for
ages.
Most display mechanisms that handle tabs work this way. However,
there is
no basis for that to conclude that indentation of code must be 8.
It can
be 8, and that makes files a bit smaller. Are small source files
important?
I don't think so. Consistency is. Pick an indentation and use it
uniformly.
[...]

My own opinion is that (a) tabstops should be 8 columns

Two!

Two or four. I admit to having been a fourist in the past, although I've
converted to twoism. Not much of an initiation ceremony, mostly tweaking
of .vimrc and indent.pro.
No argument there.

Agnostic. Providing ts=8, the results should be invisible.
 
B

Bart

Likewise, although I confess to having flirted briefly with threeism.
That was a bad move, and I abandoned it almost immediately.

I've nearly always used one space. Last time I used actual tabs, my
code would rapidly disappear off the right edge of the teletype paper
(which used 72 columns iirc).
 
B

Beej Jorgensen

Keith Thompson said:
My own opinion is that (a) tabstops should be 8 columns, and (b)
tabs should not be used in source code, only spaces.

Interestingly, the Linux kernel coding guidelines use 8 column tabs to
enforce code simplicity: if it spills over 80 columns it probably needs
to be split into a new function anyway. (Normally I'd object to this
kind of crazy blanket rule, but it seems to have served quite well over
the years.)

With 8 spaces, I always feel like my eyes have to travel too far. (It
makes it tougher to fit code in reduced margins, too, which is probably
one of the reasons for 4-space indents in K&R2.)

-Beej
 
K

Keith Thompson

Rich Webb said:
Agnostic. Providing ts=8, the results should be invisible.

Unfortunately, I have to work with code that was written with the
assumption that tabstops are every 4 columns (except for the parts
of the code that assume 8-column tabstops, and I think I've seen
some that assumes 2-column tabstops).

Any file I modify has no tabs when I'm done with it.
 
S

scott

I assume he wouldn't mind a good *long* summary if that is what it
takes ...



Of course! That can be as short as "returns success" or need a long
description (for example, if it is not clear what success means).


It does hurt, in my experience.  If you mandate comment headings like:

  Name: foo

  Arguments: bar - something
             baz - something
             bat - something

  Returns: something

then you'll never get people to document the functions properly, because
they spend themselves typing things like "len - the length". And half
the time the documentation will be outdated.


I don't touch that stuff. Look at some Unix section 2 and 3 man pages
-- that's the style I prefer. For example,

   ...
   char *strcpy(char *dest, const char *src);
   ...
   The strcpy() function copies the string pointed to by src,
   including the terminating null byte ('\0'), to the buffer pointed
   to by dest. The strings may not overlap, and the destination string
   dest must be large enough to receive the copy.

The big difference here is that you get to form complete sentences --
keeps you somewhat intellectually honest -- and you can describe the
parameters in terms of how they work together. With the
list-of-arguments style, you have to pretend they have nothing to do
with each other (like a pointer to a buffer and its length).

/Jorgen


Why would you need to pretend the arguments have nothing to do with
one another simply because they are in a list? I have used the list
format with success and each argument was given a desciption in
complete sentences as you prefer and was described in in terms of
other arguments as required so I don't see how one is any better than
the other, simply personal preference. As far as the assertion that
one method or the other results in outdated comments I would suggest
that outdated comments are an issue no matter how you format the
comments, the format of the comments does not prevent them from being
updated laziness does. The bottom line is everyone has a personal
preference, number of spaces to indent is a clasic example, for these
things but a standard needs to be established so that the code
developed at a given company all has a similar look and feel. Pick one
along with input from the team and modify it over tiume as the needs
change but make sure everyone uses it.
 
N

Nobody

A library isn't directly executed on its own.

ELF shared libraries can also be executables:

$ /lib/libc-2.9.so --help
GNU C Library stable release version 2.9, by Roland McGrath et al.
Copyright (C) 2008 Free Software Foundation, Inc.
[snip]

They don't use main() for this, though.
 
T

Tech07

Richard Heathfield said:
Do you write mainCRTStartup yourself?

"I have" (read I modified code I found elsewhere), but I don't yet use it in
production code. It is some kind of goal to do so though. For C, the
equivalent replacement code should be pretty trivial, as even the C++
"replacement" isn't bad at all. If your program doesn't use the standard
library, it may be worth a look if you want ultra-small executables (save 30
kb or so). I mean, if you don't need it, you don't need it, right? (Probably
"safer" to link it in though: not for the faint of heart).
If so, fine. But if your
implementation squirts it into the object file for you, and calls
/your/ code's entry point, then it isn't what we're talking about -
or at least not what I'm talking about, which is C's requirements.

I don't know what the standard says about implementations at that level (std
library initialization and the like).
I've written plenty of Win32 GUI programs, and never written a
WinMainCRTStartup function ever.

Most people will not, as I have noted. If you are wholistically bought-into
the language implementation, and "99%" of C developers are, you don't even
have to know that WinMainCRTStartup exists. It's for those who like to "get
their hands dirty" or do very specialized stuff. Obviously though, there is
a need for such capability and that's why compilers provide it.
So how can it be the entry point to
my C code?

It's the first thing that gets called by the platform environment. To me,
that sounds like "entry point". The whole "main()" thing is just a high
level illusion which just happens to be adequate for most. Most consider the
language and the library one thing. Some consider it distinctly 2 things.
Mix-n-match as you please (if your compiler lets you, by allowing you to
override the default entry point).
It may well be the street down which control flow must
journey (I haven't bothered to check), but it is neither my code's
front door nor even its garden gate.


And DLLs which do not contain such a function have no entry point, and
so control flow cannot enter them? Funny, then, how my DLLs work just
fine without it.

_DLLMainCRTStartup is provided for you, but it is there just like
WinMainCRTStartup is for a GUI executable. It's in an OS library you link
with to produce the DLL. It probably does the same stuff that the other
startup codes do: initialize the std library and other stuff.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top