[Maybe OT] How to convince people about the importance of ANSI standards conformance ?

A

Amarendra GODBOLE

Hi,

I am working on a legacy user space app, which has been developed
entirely in C, some 15 years ago. Needless to say, it does not even
partially conform to any standard.

My team is in the process of adding new features to this app. As a
start off, I asked them to write clean code, which conforms to certain
aspects of the ANSI standard. I am no authority on the standard, and
my knowledge is based on C Unleashed.

For that I asked them to --
1. Avoid identifier names starting with _.
I asked them to change the following structure --

typedef struct _foo {
...
} Foo;

to

typedef struct foo_ {
...
} Foo;

2. Avoid clashes with the system namespace. To avoid id names
beginning with str, is, etc.

I thought by making them aware of such issues, we can probably write
code which is more clean, easy to maintain, and partly conforming to
ANSI.

But they fail to see my point of conformance and I am faced with
issues like --
1. How will we trample the system namespace with names like
_DBGetFooRecord etc.
2. Standards etc are junk and in no way we are to conform to that. We
are going to write code the way _we_ feel it.

My defense was all that I have learned from C Unleashed, but it is
proving to ve weak. I'd like you all from clc to help me make my
defense stronger, so that I can make them see some light !

I am not sure if this mail is OT or OT (On or Off), but nevertheless I
am posting it.

Cheers,
Amarendra
 
E

E. Robert Tisdale

Amarendra said:
I am working on a legacy user space application
which has been developed entirely in C some 15 years ago.
Needless to say, it does not even partially conform to any standard.

My team is in the process of adding new features to this application.
As a start off, I asked them to write clean code
which conforms to certain aspects of the ANSI standard.
I am no authority on the standard
and my knowledge is based on C Unleashed.

For that I asked them to --

1. Avoid identifier names starting with _.
I asked them to change the following structure --

typedef struct _foo {
...
} Foo;

to

typedef struct foo_ {
...
} Foo;

Ask them to write

typedef struct Foo {
// . . .
} Foo;

instead. There is no point in cluttering up the namespace.
2. Avoid clashes with the system namespace.
To avoid id names beginning with str, is, etc.

I thought by making them aware of such issues,
we can probably write code which is more clean, easy to maintain
and partly conforming to ANSI.

But they fail to see my point of conformance
and I am faced with issues like --

1. How will we trample the system namespace
with names like _DBGetFooRecord etc.
2. Standards etc. are junk and in no way we are to conform to that.
We are going to write code the way _we_ feel it.

My defense was all that I have learned from C Unleashed
but it is proving to be weak.
I'd like you all from clc to help me make my defense stronger
so that I can make them see some light!

Unless you are the team leader, you have no business doing so.
I'm not sure how you could be a team leader supervising C programmers
without a *strong* grasp on the ANSI/ISO C standards.

If you are just another team member, try listening instead of talking.
Try to learn from more experienced team members.
Beware of their bad habits and endeavor not to acquire them yourself.
 
J

Jack Klein

Hi,

I am working on a legacy user space app, which has been developed
entirely in C, some 15 years ago. Needless to say, it does not even
partially conform to any standard.

My team is in the process of adding new features to this app. As a
start off, I asked them to write clean code, which conforms to certain
aspects of the ANSI standard. I am no authority on the standard, and
my knowledge is based on C Unleashed.

For that I asked them to --
1. Avoid identifier names starting with _.
I asked them to change the following structure --

typedef struct _foo {
...
} Foo;

to

typedef struct foo_ {
...
} Foo;

Note that it is almost never necessary, or particularly helpful, to
provide both a structure tag and a typedef for a structure definition.
Don't do this unless you need it.
2. Avoid clashes with the system namespace. To avoid id names
beginning with str, is, etc.

I thought by making them aware of such issues, we can probably write
code which is more clean, easy to maintain, and partly conforming to
ANSI.

But they fail to see my point of conformance and I am faced with
issues like --
1. How will we trample the system namespace with names like
_DBGetFooRecord etc.

Maybe you will, maybe you won't. That's exactly the point, that
namespace is reserved for the language standard (__FILE__, and such)
and for the implementation, meaning the compiler and it's headers.

You can come up with some incredibly hard-to-find bugs when you try to
build your old code with a new compiler, or even a newer version of
your current compiler, and somewhere in the compiler internals or in
some private include file is a macro or intrinsic symbol that matches
one of your identifiers.
2. Standards etc are junk and in no way we are to conform to that. We
are going to write code the way _we_ feel it.

Is this a volunteer open source project or a commercial product? Are
you dealing with professional programmers or trying to teach a class
of crabby pre-schoolers?

One of the reasons for the incredible amount of defective software
today is the cowboy know-it-all attitude of far too many programmers.
Those who still see programming as an art and not as a science or
engineering discipline might be beyond help.

If the worked for me, they would change their attitudes or find
themselves looking for a new job.
 
R

Richard Heathfield

Jack said:
Note that it is almost never necessary, or particularly helpful, to
provide both a structure tag and a typedef for a structure definition.
Don't do this unless you need it.

Fair comment, but I'd like to raise some points in its favour: 1) it can
make life easier for some code analysis tools; 2) it never hurts, provided
one has an even remotely decent naming convention for types; 3) it makes
opaque typing slightly easier; 4) if you do it /all/ the damn time, it's
there when you /do/ need it, without your having to think about what
changed.

<snip>

[Because of snippage, I should point out that the OP is railing against the
following attitude, not espousing it!]
Is this a volunteer open source project or a commercial product? Are
you dealing with professional programmers or trying to teach a class
of crabby pre-schoolers?

To me, they don't sound like either group. Rather, they're simply perfectly
normal C programmers who haven't yet discovered comp.lang.c. There are
quite a few of them out there, you know.
One of the reasons for the incredible amount of defective software
today is the cowboy know-it-all attitude of far too many programmers.
Those who still see programming as an art and not as a science or
engineering discipline might be beyond help.

I'll buy "and not", since I see it as an art /and/ a science /and/ a craft.
 
N

Nils Petter Vaskinn

Jack Klein wrote:

I'll buy "and not", since I see it as an art /and/ a science /and/ a
craft.

And a good artits would get the paint on the canvas not on the floor. It
is an art, but that doesn't mean all artist are good artists.
 
P

pete

Amarendra said:
Hi,

I am working on a legacy user space app, which has been developed
entirely in C, some 15 years ago. Needless to say, it does not even
partially conform to any standard.

Is portability an issue ?
Is the software intended to run on only just one kind of machine,
which is exactly the same as the one that your testing with ?

If the answers are not no and yes respectively, then your case
is valid, and you need a more effective presentation,
as you have already stated.

If the answers are no and yes respectively, then maybe you should
just try to exert your influence again when the next project starts.
If portability is not a requirement now, and if that
requirement changes, then that's a new assignment for new money.
 
C

CBFalconer

Jack said:
(e-mail address removed) (Amarendra GODBOLE) wrote in comp.lang.c:
.... snip ...

Note that it is almost never necessary, or particularly helpful, to
provide both a structure tag and a typedef for a structure definition.
Don't do this unless you need it.

<nit> If the "..." includes a "struct foo_ *id" field, it is
necessary. </nit>
 
D

Darrell Grainger

Hi,

I am working on a legacy user space app, which has been developed
entirely in C, some 15 years ago. Needless to say, it does not even
partially conform to any standard.

My team is in the process of adding new features to this app. As a
start off, I asked them to write clean code, which conforms to certain
aspects of the ANSI standard. I am no authority on the standard, and
my knowledge is based on C Unleashed.

What you are asking them to do is a lot of work with no visible benefit.
From a management point of view I would see this as making a lot of
changes when no actual change to what the code does. I'd be worried that
changing the code 'unnecessarily' will add risk. What if I decide to
change all the _foo to foo_ and there is aleady a foo_ in the system? I
cannot just change all the names without first checking that the new name
does not exist. In other words, you are probably facing a "if it ain't
broke, don't fix it" additude.

I believe Martin Fowler wrote a good book on refactoring. His reason for
refactoring was to make the code esier to maintain but I would guess that
a lot of what he has to say will apply to your situation as well. You are
basically refactoring the code. So go to some where like amazon.com and
search for Martin Fowler's book on Refactoring.

Additionally, you want to do this in stages. The budget might not handle
having everyone just refactoring for a few months. I'd guess that you will
still need to add functionality while refactoring.
For that I asked them to --
1. Avoid identifier names starting with _.
I asked them to change the following structure --

typedef struct _foo {
...
} Foo;

to

typedef struct foo_ {
...
} Foo;

Why? That is the question I always have to answer in order to get the
developers at my site to accept a new procedure. If it does not make sense
to them they will not do it. Additionally, they will often do things that
have benefit for them but not the organization as a whole. In those cases
they are usually not rewarded for refactoring the code. I need to get
management on side. Once management indicates they will reward developers
for refactoring the code they are more inclined to do it.
2. Avoid clashes with the system namespace. To avoid id names
beginning with str, is, etc.

Why? Wouldn't the compiler give a warning if I used a function name that
clashed with a system function? Then I'd know to change that. Think of
reasons they will feel your suggestions are not necessary and have
something to counter with.
I thought by making them aware of such issues, we can probably write
code which is more clean, easy to maintain, and partly conforming to
ANSI.

Do they get rewarded for cleaning up the code? Or is this coming across as
a punishment, e.g. everyone wrote bad code and now you are going to have
to clean it up.
But they fail to see my point of conformance and I am faced with
issues like --
1. How will we trample the system namespace with names like
_DBGetFooRecord etc.
2. Standards etc are junk and in no way we are to conform to that. We
are going to write code the way _we_ feel it.

My defense was all that I have learned from C Unleashed, but it is
proving to ve weak. I'd like you all from clc to help me make my
defense stronger, so that I can make them see some light !

It all boils down to what is the benefit. Show them examples of how things
can go wrong. Also, be open to the fact that this might take time. Also,
consider the market. Can they afford to refactor the code? Is there so
little profit that they cannot afford the extra work? If you try to get
them doing everything at once you will get nothing. Try a little at a
time.
 
E

E. Robert Tisdale

Richard said:
Fair comment, but I'd like to raise some points in its favor:
1) it can make life easier for some code analysis tools;
2) it never hurts, provided that
one has an even remotely decent naming convention for types;

I pollutes the namespace unnecessarily.
3) it makes opaque typing slightly easier;
4) if you do it /all/ the damn time, it's there when you /do/ need it,
without your having to think about what changed.

typedef struct Foo {
struct Foo* p;
// ...
} Foo;

or better yet:

typedef struct Foo Foo;
struct Foo {
Foo* p;
// ...
};
 
M

Michael Wojcik

Why? Wouldn't the compiler give a warning if I used a function name that
clashed with a system function? Then I'd know to change that.

It's not clear to me whether you meant this as a serious objection to
rewriting code to avoid the implementation namespace, or only as a
proleptic example of an objection someone else might raise. In any
event, it's easily dealt with. There's no reason to believe the
implementation *would* warn you if you defined a function using a
name from the implementation namespace. In itself that doesn't violate
a constraint.

If there's a prototype in scope for a function of that name, and your
function doesn't match it, then yes, you ought to get a diagnostic
(C90 6.3.2.2 constraint). And it's certainly possible in some cases
for an implementation to note when a translation unit invades the
implementation namespace and issue a diagnostic - but I can't think
of any I've used that do.

Just the other day I had to correct some old code that stepped fatally
on an implementation-defined function. The function name in question
wasn't a reserved one, but it was a "system function" (provided by the
implementation). No diagnostic was issued during compilation, and the
implementation - gcc + glibc, on a relatively recent Linux distribution
- is a popular one.
 
R

Richard Heathfield

E. Robert Tisdale said:
I pollutes the namespace unnecessarily.

If one has an even remotely decent naming convention for types, then this
"pollution" is immaterial.
typedef struct Foo {
struct Foo* p;
// ...
} Foo;

This can confuse some code analysis tools (e.g. Visual Studio's "go to
definition" feature won't know which Foo you mean).
or better yet:

typedef struct Foo Foo;
struct Foo {
Foo* p;
// ...
};

Same applies.
 
E

E. Robert Tisdale

Richard said:
If one has an even remotely decent naming convention for types,
then this "pollution" is immaterial.


This can confuse some code analysis tools (e.g. Visual Studio's "go to
definition" feature won't know which Foo you mean).

I don't think that it is a good idea to cobble your code
just to accommodate some defective tool.
 
J

Jack Klein

Jack said:
Note that it is almost never necessary, or particularly helpful, to
provide both a structure tag and a typedef for a structure definition.
Don't do this unless you need it.

Fair comment, but I'd like to raise some points in its favour: 1) it can
make life easier for some code analysis tools; 2) it never hurts, provided
one has an even remotely decent naming convention for types; 3) it makes
opaque typing slightly easier; 4) if you do it /all/ the damn time, it's
there when you /do/ need it, without your having to think about what
changed.

<snip>

[Because of snippage, I should point out that the OP is railing against the
following attitude, not espousing it!]
Is this a volunteer open source project or a commercial product? Are
you dealing with professional programmers or trying to teach a class
of crabby pre-schoolers?

To me, they don't sound like either group. Rather, they're simply perfectly
normal C programmers who haven't yet discovered comp.lang.c. There are
quite a few of them out there, you know.

Sadly I agree with you, as far as your statement goes, which is not
far enough. Rather they are simply typical programmers in any
language. There are many more sources of enlightenment than just
comp.lang.c, or all of usenet.

Although it is not entirely the fault of the programmers. The
educational systems of many countries, including the US, is sadly
deficient. And the priorities of far too many businesses are
inappropriate as well.
I'll buy "and not", since I see it as an art /and/ a science /and/ a craft.

Simply put, computer programming is still too new a field. It is not
possible to do thorough analysis, nor to pass truly objective
judgement.

No educational institution would give a graduate a medical degree
without a demonstrated understanding of anatomy. Nor a structural
engineer without a thorough and proven grounding in the objective
standards of the field.

But they think nothing of giving people computer science or
engineering degrees who think that this is proper and correct:

#include <stdio.h>
#include <conio.h>

void main(void)
{
printf("Hello, World\n");
getch();
}
 
A

Amarendra GODBOLE

[...snipped...]
It all boils down to what is the benefit. Show them examples of how things
can go wrong. Also, be open to the fact that this might take time. Also,

[...snipped...]

Thanks folks. All replies have definitely given me a direction to work
on. Here is what I have decided to do:
1. Listen more.
2. Be more knowledgable about the ANSI/ISO C standard.
3. Think from all angles, especially from the management perspective
too.
4. Trouble you all, if things are hazy still !

BTW, I am a team member, and my effort was in a direction of making
other programmers' aware of --
1. Standardization and its benefits.
2. ANSI/ISO C standards.
3. comp.lang.c (They are not aware that this exists !)
4. Initiate a thought process on writing better and more maintainable
code.

The path that I chose initially was probably asking too much of them,
without really showing them what the benefits are. I surely need to
re-visit that, and rebuild my case in a more proper way.

Thanks a lot to comp.lang.c

Cheers,
Amar
 
E

E. Robert Tisdale

Amarendra said:
Here is what I have decided to do:
1. Listen more.
2. Be more knowledgeable about the ANSI/ISO C standard.
3. Think from all angles,
especially from the management perspective too.
4. Trouble you all, if things are hazy still!

BTW, I am a team member and my effort was in a direction of making
in a direction of making other programmers' aware of --
1. Standardization and its benefits.
2. ANSI/ISO C standards.
3. comp.lang.c (They are not aware that this exists!)
4. Initiate a thought process
on writing better and more maintainable code.

The path that I chose initially was probably asking too much of them,
without really showing them what the benefits are. I surely need to
re-visit that, and rebuild my case in a more proper way.

"A scientific truth does not triumph by convincing its opponents
and making them see the light,
but rather because its opponents eventually die
and a new generation grows up that is familiar with it."
-- Max Planck

Our profession is evolutionary -- not revolutionary.
It must wait for the Olde Tymers to retire (or die)
before it can advance. Be patient.
 
C

Christian Bau

The path that I chose initially was probably asking too much of them,
without really showing them what the benefits are. I surely need to
re-visit that, and rebuild my case in a more proper way.

I'll give you a few advantages of writing Standard C code that are not
mentioned too often, and they come purely from a management/time savings
perspective:

1. If your code base is Standard C, then _any_ C programmer can
understand the code. You might be writing code for an embedded system
that I haven't even heard of; if it is Standard C then _I_ can read your
code, understand it, find bugs etc. If it is not Standard C but specific
to that implementation, then you have to find someone how knows all
those specifics.

2. There is lots of code where the programmer thinks "it might be
undefined behavior, but it works". That's fine if your program works.
What if there are bugs, and someone has to fix the problem? If there are
no obvious problems in the code, but it doesn't work, then obviously
there must be hidden problems. So I look for suspicious things and fix
them. Guess what: Every bit of undefined behavior, even if it works,
causes me to do extra work at debugging time.

3. It is not only important that your code is good, it is also important
that people have confidence in it. If I look at 10,000 lines of code
that I haven't seen before, and I find three cases of undefined behavior
in the first 50 lines, then I don't trust this code. That fact alone
will cost time and money. For example, code that is badly written must
be tested more thouroughly and that costs money again.

4. When reading code, everything that interrupts the flow costs time.
And programmers read a lot of code. Bad programming style interrupts the
flow. Code that would create warnings if the programmer hadn't turned
all warnings off interrupts the flow. Undefined behavior certainly
interrupts the flow.
 
C

CBFalconer

Amarendra said:
[...snipped...]

The path that I chose initially was probably asking too much
of them, without really showing them what the benefits are.
I surely need to re-visit that, and rebuild my case in a more
proper way.

There is hope for this one. In a day or two he has gone from
insufferable to a cooperative teachable human being, with
leadership qualities.
 
R

Richard Bos

E. Robert Tisdale said:
I don't think that it is a good idea to cobble your code
just to accommodate some defective tool.

And for once, I agree with Mr. Tisdale. I want my code to be easy for
_me_ to read. If the computer can't make sense of perfectly correct
code, it's time to get another program.

Richard
 
R

Richard Heathfield

Richard said:
And for once, I agree with Mr. Tisdale.

Well, I don't think I'm cobbling the code; I think I'm making it more
readable, for me at least. As it happens, I rarely use Visual Studio at
home (which is the only place my coding conventions apply, unless I'm
fortunate enough to work at a site where they either use my conventions
already or are prepared to change them for my benefit!) - but my convention
/does/ have the benefit of being easier for Visual Studio to sort out
(incidentally, if the tag and the typedef /are/ the same, Visual Studio
asks which you mean, so I think it's probably unfair to call it "defective"
in this regard, at least).
I want my code to be easy for
_me_ to read. If the computer can't make sense of perfectly correct
code, it's time to get another program.

My convention is:

struct Foo_
{
...
};

typedef struct Foo_ Foo;

I do not find this hard to read.
 
P

pete

Richard said:
Well, I don't think I'm cobbling the code; I think I'm making it more
readable, for me at least.

My convention is:

struct Foo_
{
...
};

typedef struct Foo_ Foo;

I do not find this hard to read.

I don't like the type having the exact same spelling as the object,
either.
 

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

Forum statistics

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

Latest Threads

Top