Not quite standard... but socially acceptable

  • Thread starter Tomás Ó hÉilidhe
  • Start date
T

Tomás Ó hÉilidhe

I mainly keep my code as standard as possible, but I need to branch
out just a tad.

Firstly, if you're writing console programs for a system that has a
screen, a keyboard, and a commandline, then is there any commonly used
library for doing things like clearing the screen, or taking a single
key press from the user?

Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.
 
B

Ben Pfaff

Tomás Ó hÉilidhe said:
Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.

C99 no longer requires all declarations to be at the beginning of
a block. Perhaps you can require some level of C99 conformance
from the compilers that you support.
 
J

jacob navia

Tomás Ó hÉilidhe said:
I mainly keep my code as standard as possible, but I need to branch
out just a tad.

Firstly, if you're writing console programs for a system that has a
screen, a keyboard, and a commandline, then is there any commonly used
library for doing things like clearing the screen, or taking a single
key press from the user?

It depends if you want the unix flavor, or the windows flavor
Unix uses a "curses" library to control the screen/keyboard.

Under windows most compilers provide
keypressed()

or similar stuff.

Under windows Microsoft provides a Console API that does all the
console handling (console colors, reading text from the console, etc)
Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.

This is standard C. The standard allows explicitly to declare variables
anywhere.
 
D

Dann Corbit

Tomás Ó hÉilidhe said:
I mainly keep my code as standard as possible, but I need to branch
out just a tad.

Firstly, if you're writing console programs for a system that has a
screen, a keyboard, and a commandline, then is there any commonly used
library for doing things like clearing the screen,

19.4: How can I clear the screen?
How can I print text in color?
How can I move the cursor to a specific x, y position?

A: Such things depend on the terminal type (or display) you're
using. You will have to use a library such as termcap,
terminfo, or curses, or some system-specific routines, to
perform these operations. On MS-DOS systems, two functions
to look for are clrscr() and gotoxy().

For clearing the screen, a halfway portable solution is to print
a form-feed character ('\f'), which will cause some displays to
clear. Even more portable (albeit even more gunky) might be to
print enough newlines to scroll everything away. As a last
resort, you could use system() (see question 19.27) to invoke
an operating system clear-screen command.

References: PCS Sec. 5.1.4 pp. 54-60, Sec. 5.1.5 pp. 60-62.
or taking a single
key press from the user?

19.1: How can I read a single character from the keyboard without
waiting for the RETURN key? How can I stop characters from
being echoed on the screen as they're typed?

A: Alas, there is no standard or portable way to do these things in
C. Concepts such as screens and keyboards are not even
mentioned in the Standard, which deals only with simple I/O
"streams" of characters.

At some level, interactive keyboard input is usually collected
and presented to the requesting program a line at a time. This
gives the operating system a chance to support input line
editing (backspace/delete/rubout, etc.) in a consistent way,
without requiring that it be built into every program. Only
when the user is satisfied and presses the RETURN key (or
equivalent) is the line made available to the calling program.
Even if the calling program appears to be reading input a
character at a time (with getchar() or the like), the first call
blocks until the user has typed an entire line, at which point
potentially many characters become available and many character
requests (e.g. getchar() calls) are satisfied in quick
succession.

When a program wants to read each character immediately as it
arrives, its course of action will depend on where in the input
stream the line collection is happening and how it can be
disabled. Under some systems (e.g. MS-DOS, VMS in some modes),
a program can use a different or modified set of OS-level input
calls to bypass line-at-a-time input processing. Under other
systems (e.g. Unix, VMS in other modes), the part of the
operating system responsible for serial input (often called the
"terminal driver") must be placed in a mode which turns off
line-at-a-time processing, after which all calls to the usual
input routines (e.g. read(), getchar(), etc.) will return
characters immediately. Finally, a few systems (particularly
older, batch-oriented mainframes) perform input processing in
peripheral processors which cannot be told to do anything other
than line-at-a-time input.

Therefore, when you need to do character-at-a-time input (or
disable keyboard echo, which is an analogous problem), you will
have to use a technique specific to the system you're using,
assuming it provides one. Since comp.lang.c is oriented towards
those topics that the C language has defined support for, you
will usually get better answers to other questions by referring
to a system-specific newsgroup such as comp.unix.questions or
comp.os.msdos.programmer, and to the FAQ lists for these groups.
Note that the answers may differ even across variants of
otherwise similar systems (e.g. across different variants of
Unix); bear in mind when answering system-specific questions
that the answer that applies to your system may not apply to
everyone else's.

However, since these questions are frequently asked here, here
are brief answers for some common situations.

Some versions of curses have functions called cbreak(),
noecho(), and getch() which do what you want. If you're
specifically trying to read a short password without echo, you
might try getpass(). Under Unix, you can use ioctl() to play
with the terminal driver modes (CBREAK or RAW under "classic"
versions; ICANON, c_cc[VMIN] and c_cc[VTIME] under System V or
POSIX systems; ECHO under all versions), or in a pinch, system()
and the stty command. (For more information, see <sgtty.h> and
tty(4) under classic versions, <termio.h> and termio(4) under
System V, or <termios.h> and termios(4) under POSIX.) Under
MS-DOS, use getch() or getche(), or the corresponding BIOS
interrupts. Under VMS, try the Screen Management (SMG$)
routines, or curses, or issue low-level $QIO's with the
IO$_READVBLK function code (and perhaps IO$M_NOECHO, and others)
to ask for one character at a time. (It's also possible to set
character-at-a-time or "pass through" modes in the VMS terminal
driver.) Under other operating systems, you're on your own.

(As an aside, note that simply using setbuf() or setvbuf() to
set stdin to unbuffered will *not* generally serve to allow
character-at-a-time input.)

If you're trying to write a portable program, a good approach is
to define your own suite of three functions to (1) set the
terminal driver or input system into character-at-a-time mode
(if necessary), (2) get characters, and (3) return the terminal
driver to its initial state when the program is finished.
(Ideally, such a set of functions might be part of the C
Standard, some day.) The extended versions of this FAQ list
(see question 20.40) contain examples of such functions for
several popular systems.

See also question 19.2.

References: PCS Sec. 10 pp. 128-9, Sec. 10.1 pp. 130-1; POSIX
Sec. 7.

Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.

C99 allows it. If you use GCC on all your platforms, you can get away with
it.
If you need portability, you can always make a block for the exclusive
purpose of defining a new variable:

....
{
char s[256];
do_stuff_with_s(s);
}
 
K

Keith Thompson

jacob navia said:
Tomás Ó hÉilidhe wrote: [...]
Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.

This is standard C. The standard allows explicitly to declare variables
anywhere.

What jacob isn't bothering to tell you is that this is a new feature
in the current C standard, issued in 1999 (and therefore referred to
as "C99"). Most C compilers do not yet fully support the C99
standard; they instead support the earlier C90 or C95 standard (C95
was a minor update to C90).

I won't tell you that you shouldn't use C99-specific features. I will
tell you that, by doing so, you risk limiting the portability of your
code (a risk that, I hope, will diminish over time).

If you want maximal portability, you can program in the common subset
of C90 and C99 (basically C90 without implicit int and without trying
to use the few new keywords as identifiers).
 
J

jacob navia

Keith said:
jacob navia said:
Tomás Ó hÉilidhe wrote: [...]
Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.
This is standard C. The standard allows explicitly to declare variables
anywhere.

What jacob isn't bothering to tell you is that this is a new feature
in the current C standard, issued in 1999 (and therefore referred to
as "C99").

Can't you read man?

I said:
This is standard C. The standard allows explicitly to declare variables
anywhere.

"New" was in 1999, or maybe 2003...
In 2008 is no longer "new". Besides, as the OP says:
>>> [snip] ... I've seen that a hell
>>> of a lot of C compilers allow you to define objects wherever you want,

So, it more common than what you think
Most C compilers do not yet fully support the C99
standard; they instead support the earlier C90 or C95 standard (C95
was a minor update to C90).

Most of them support this feature, as the OP says.

I won't tell you that you shouldn't use C99-specific features. I will
tell you that, by doing so, you risk limiting the portability of your
code (a risk that, I hope, will diminish over time).

The OP did not mention any portability requirements
other than "socially acceptable".
If you want maximal portability, you can program in the common subset
of C90 and C99 (basically C90 without implicit int and without trying
to use the few new keywords as identifiers).

By using standard C you promote the standard. I think it should
be done.
 
C

CBFalconer

jacob said:
It depends if you want the unix flavor, or the windows flavor
Unix uses a "curses" library to control the screen/keyboard.

Under windows most compilers provide keypressed()

These things are system specific, and discussion belongs on system
specific newsgroups. They are off-topic here.
 
K

Keith Thompson

jacob navia said:
Keith said:
jacob navia said:
Tomás Ó hÉilidhe wrote: [...]
Secondly, is it OK, do you think, to flout C's rule of having to
define all objects at the beginning of a block? I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,
and I think it leads to far neater code, especially when it comes to
being able to use const in places where you previously weren't able.
This is standard C. The standard allows explicitly to declare variables
anywhere.

What jacob isn't bothering to tell you is that this is a new feature
in the current C standard, issued in 1999 (and therefore referred to
as "C99").

Can't you read man?

Yes, I can. Can you?
I said:
This is standard C. The standard allows explicitly to declare variables
anywhere.

Yes, that's true, and I said nothing that contradicts that.
"New" was in 1999, or maybe 2003...
In 2008 is no longer "new". Besides, as the OP says:

As long as the C99 standard is less widely supported than the C90
standard, it's *effectively* new, regardless of its chronological age.
[snip] ... I've seen that a hell
of a lot of C compilers allow you to define objects wherever you want,

So, it more common than what you think

That particular feature is fairly common, yes. I didn't say it
wasn't.
Most of them support this feature, as the OP says.

I didn't say otherwise.
The OP did not mention any portability requirements
other than "socially acceptable".

The OP seemed to be under the impression that mixing declarations and
statements within a block is a common, but non-standard, extension.

You just told him that it's "standard C", which is quite correct but
incomplete. I provided more information. Why do you have a problem
with that?
By using standard C you promote the standard. I think it should
be done.

So promote the standard. I have no problem with that.

It is a fact (unfortunately) that C99 is not yet as widely supported
as C90. I conveyed that information to the OP, who can use it in
whatever way he chooses. I didn't even disagree with anything you
wrote. If you have a problem with that, that's just too bad.
 
B

Bartc

Richard Heathfield said:
jacob navia said:

(By which you mean C99.) That's fine - that is your opinion, to which you
are entitled - but in the real world some of like our code to compile, so
we *can't* use these extra features. Even if they compile *here*, tomorrow
we might need to compile them over *there*... When C99 is portable, I'll
start using it. Until then, I can't. And, if you use your own compiler,
neither can you.

If everyone took this attitude, there would be no progress at all on C
standards, and no-one would write new compilers.

(Although I know the extra stuff they came up with in C99 isn't that
riveting, especially after 9 years.)

Now, if there was a tool, written in C90, that took C99 source and converted
it to C90, would that make you happier about using C99?

The tool would only be used over 'there' if a native C99 system was not
available.

(I think a few things in C99 cannot be translated that easily, but ignore
those. I'm assuming such a tool -- or perhaps utility -- is much easier to
write than a full compiler.)
 
R

Rui Maciel

On Fri, 04 Apr 2008 05:15:51 +0000, Richard Heathfield wrote:

(By which you mean C99.) That's fine - that is your opinion, to which
you are entitled - but in the real world some of like our code to
compile, so we *can't* use these extra features. Even if they compile
*here*, tomorrow we might need to compile them over *there*... When C99
is portable, I'll start using it. Until then, I can't. And, if you use
your own compiler, neither can you.

Correct me if I'm wrong but I believe that you are confusing the concept
of "portability" with "the compiler that I use doesn't support this
particular standard".


Rui Maciel
 
R

Rui Maciel

What jacob isn't bothering to tell you is that this is a new feature in
the current C standard, issued in 1999 (and therefore referred to as
"C99"). Most C compilers do not yet fully support the C99 standard;
they instead support the earlier C90 or C95 standard (C95 was a minor
update to C90).

What exactly do you mean by "most C compilers"? Are we talking about the
number of makes and models released or are we talking about install base?


Rui Maciel
 
K

Keith Thompson

Rui Maciel said:
On Fri, 04 Apr 2008 05:15:51 +0000, Richard Heathfield wrote:



Correct me if I'm wrong but I believe that you are confusing the concept
of "portability" with "the compiler that I use doesn't support this
particular standard".

The two concepts are closely related. If compilers that support a
given standard are not available, or not easily or cheaply available,
for a given platform or for a wide variety of platforms, then code
that depends on that standard is less portable than it would otherwise
be. What confusion are you referring to?
 
K

Keith Thompson

Rui Maciel said:
What exactly do you mean by "most C compilers"? Are we talking about the
number of makes and models released or are we talking about install base?

Take your pick. As far as I know, full C99 support is rare by either
measure.

And just in case anyone thinks I'm attacking the C99 standard, I wish
this were not the case. (This is not directed at you, Rui.)
 
B

Bartc

Richard said:
Bartc said:
[C99...] but in the real world some of like our code to
compile, so we *can't* use these extra features. Even if they
compile *here*, tomorrow we might need to compile them over
*there*... When C99 is portable, I'll start using it. Until then, I
can't. And, if you use your own compiler, neither can you.

If everyone took this attitude, there would be no progress at all on
C standards, and no-one would write new compilers.

The C89 Standard demonstrates that this isn't the case. When C89 came
out, implementors rushed to conform to it, as a result of which C89
is portable to just about the entire known universe.

For implementors to treat a new standard in the same way, it has to be
worth their while to implement it, which means that it should focus on
stuff that everyone wants and isn't too stupidly hard to implement.
(Although I know the extra stuff they came up with in C99 isn't that
riveting, especially after 9 years.)

Um, quite so.
Now, if there was a tool, written in C90, that took C99 source and
converted it to C90, would that make you happier about using C99?

Yes, absolutely. Are you offering to write one?

No. I have thought about it, but I need more C experience.
Can't. Or at least, this would mean that those who need portability
must restrict themselves to the C99 subset that can be handled by the
translator.

That's workable.
I should imagine so, yes - but I don't quite see how it would handle
even something as trivial as long long.

Long long is one example of a problem area. Emulation is of course,
possible, but is not satisfactory. Translating according to knowledge of the
target compiler is possible, but inelegant compared to a one-time
translation to C90.

Probably there are library functions that will cause problems.

But a translator concentrating on the easier-to-do extensions may be
worthwhile, especially if a few extra extensions are thrown in such as some
of those in gcc which are more fun that the C99 ones.

(The translator cannot attempt too much beyond what is possible with
existing compilers, otherwise it would have to be used all the time. The
idea is for a porting tool that will encourage use of existing language
extensions.)
 
J

jacob navia

Richard said:
Rui Maciel said:


Which compiler that I use did you have in mind? gcc?

You are using a version of gcc from the last century. And you
refuse to change. THEN you say that the C99 support is not there?

The specific feature this user has named it IS supported by gcc.
 
R

Rui Maciel

The two concepts are closely related. If compilers that support a given
standard are not available, or not easily or cheaply available, for a
given platform or for a wide variety of platforms, then code that
depends on that standard is less portable than it would otherwise be.
What confusion are you referring to?

Not having a standard-compliant compiler doesn't mean that the code
written according to that particular standard isn't portable.

A user may complain that he doesn't possess a compiler which complies to
a certain standard. Nonetheless, that doesn't entitle him to redefine
terms which carry a very specific meaning, specially if he does that just
to be able to criticize the standard he can't/doesn't want to adopt.


Rui Maciel
 
R

Rui Maciel

Which compiler that I use did you have in mind? gcc? Microsoft Visual C?
Borland C? LE370? C/370? CodeWarrior? Much of my code has to port *not
only* to all of these compilers (none of which currently conform to
C99), but also (in some cases) *any* other conforming C compiler.

When *all* my users' compilers support C99, that will be the time to
switch. At present, as far as I am aware, none of my users' compilers
conform to C99[1], so there is still a little way to go.

Correct me if I'm wrong but that doesn't mean that the C99 standard isn't
portable. That just means that you are forced to work with some compilers
that don't comply with the C99 standard.


Rui Maciel
 
D

dj3vande

Rui Maciel said:
Correct me if I'm wrong but that doesn't mean that the C99 standard isn't
portable. That just means that you are forced to work with some compilers
that don't comply with the C99 standard.

Can a standard really be considered portable if no major compiler
implements it?


dave
 
F

Flash Gordon

Richard Heathfield wrote, On 04/04/08 21:23:

Now, could you please explain in what way you think C99 *is* portable,
given that practically no conforming C99 compilers exist?

You can put a copy of the C99 standard on a memory card or USB stick etc
and carry it around with you very easily ;-)
 
J

jacob navia

Richard said:
And I am *not* going to ask my users to invoke their
compiler in a non-conforming mode, just so that I can use some features
that I'm doing perfectly well without, thank you.

Since Mr Heathfield insists using gcc in -ansic and NOT -std=c99 mode
gcc will NOT compile c99.

THEN it follows that c99 is *nowhere implemented* etc.

The key here is:
> so that I can use some features
> that I'm doing perfectly well without,

He doesn't like c99.

For whatever reasons I do not care. But he should stop praising
"standard C" because what he is using is not standard C.

I will not answer this polemic since it has been recooked too
many times to have any taste any more.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top