473,890 Members | 2,038 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is C99 the final C?

I was just thinking about this, specifically wondering if there's any
features that the C specification currently lacks, and which may be
included in some future standardization .

Of course, I speak only of features in the spirit of C; something like
object-orientation, though a nice feature, does not belong in C.
Something like being able to #define a #define would be very handy,
though, e.g:

#define DECLARE_FOO(bar ) #define FOO_bar_SOMETHI NG \
#define FOO_bar_SOMETHI NG_ELSE

I'm not sure whether the features of cpp are even included in the C
standard though (and GCC has definitely taken quite a nonstandard approach
with regards to certain token expansions and whatnot), but that's one area
of improvement I see.

I would also like to see something along the lines of C++ templating,
except without the really kludgy implementation that the C++ folks decided
to go to ( and without the OOP ).

.... Mike pauses for the sound of a thousand *plonks*

Templates save a lot of time when it comes to commonly-used data
structures, and as they are entirely implemented at compile-time and don't
include, by their definition, OOP (although they can be well suited to
it), I think they would be a nice addition and in the spirit of C.

Your thoughts? I'm sure there's some vitriol coming my way but I'm
prepared 8)

--
Mike's Patented Blocklist; compile with gcc:

i=0;o(a){printf ("%u",i>>8*a&25 5);if(a){printf (".");o(--a);}}
main(){do{o(3); puts("");}while (++i);}

Nov 13 '05
193 9704
nrk
Paul Hsieh wrote:
au***@axis.com says...
On Fri, 12 Dec 2003, Paul Hsieh wrote:
> Sidney Cadot wrote:
> > What is your excuse for not having the standard? A free draft (N869)
> > is also available.
>
> The standard does not tell me how to do the job of coding. Although
> it may cause the occasional portability problem, having the raw source
> of the C library is surprisingly more useful. For example, please
> locate for me where in the standard it says that fgets() ignores '\0'
> that are consumed -- then locate where in the standard it says its the
> only string function which does this.


I'm not sure what you mean when you say "fgets() ignores '\0' that are
consumed." Can you elaborate on this, please?


1) Write a program that takes input from stdin line by line using fgets(),
and accumulates the result into an MD5 hash.

2) Now redirect an arbitrary file into it (assuming UNIX or Windows-like
redirection facilities.)

Ok, first step, of course, is to reopen the stdin as binary. (If all this
seems hoakey to you, just open any file in which someone previous
performed an
fwrite with some number of '\0' s in it instead.) But after that you
discover that its impossible to know for sure exactly how much data each
fgets() operations reads!

- strlen() is just plain wrong because earlier encountered '\0's don't
correspond to the where the first '\n' or bufferlength-1 is encountered.
- scanning for '\n' is insufficient on the very last line of the file
because
it might really have early terminated by an earlier '\0'

In short, fgets() does not leave you with a deterministic way of knowing
how much data was really read unless you outlaw '\0' from the input
stream.


Since we are talking about a binary input stream, use of ftell, some simple
arithmetic, and the contents of the buffer returned by fgets will provide
all the information you want.

-nrk.
Nov 14 '05 #171
ra*********@dea dbeef.verizon.n et says...
Paul Hsieh wrote:
au***@axis.com says...
I'm not sure what you mean when you say "fgets() ignores '\0' that are
consumed." Can you elaborate on this, please?


1) Write a program that takes input from stdin line by line using fgets(),
and accumulates the result into an MD5 hash.

2) Now redirect an arbitrary file into it (assuming UNIX or Windows-like
redirection facilities.)

Ok, first step, of course, is to reopen the stdin as binary. (If all this
seems hoakey to you, just open any file in which someone previous
performed an
fwrite with some number of '\0' s in it instead.) But after that you
discover that its impossible to know for sure exactly how much data each
fgets() operations reads!

- strlen() is just plain wrong because earlier encountered '\0's don't
correspond to the where the first '\n' or bufferlength-1 is encountered.
- scanning for '\n' is insufficient on the very last line of the file
because
it might really have early terminated by an earlier '\0'

In short, fgets() does not leave you with a deterministic way of knowing
how much data was really read unless you outlaw '\0' from the input
stream.


Since we are talking about a binary input stream, use of ftell, some simple
arithmetic, and the contents of the buffer returned by fgets will provide
all the information you want.


ftell() is fine for files that are at most LONG_MAX bytes long. I.e., even if
you expect single lines the be less than LONG_MAX bytes in length, it doesn't
help if in total they exceed this limit.

As an alternative, compare this to something like what you find here:

http://www.azillionmonkeys.com/qed/userInput.html

There's no such issue in the function shown there.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 14 '05 #172
In article <3F************ ***@yahoo.com>, cb********@yaho o.com says...
Paul Hsieh wrote:
... snip ...
In short, fgets() does not leave you with a deterministic way of
knowing how much data was really read unless you outlaw '\0' from
the input stream.


IF this is a potential problem, you are allowed to build your
input around fgetc, getc, or even getchar.


Which kind of makes you wonder exactly what value the standard C library is
giving you. If this whole "ignore '\0'" feature of fgets() was a somehow
necessary or useful feature which one could easily map to a more general
solution there would be no issue. But its not.

--
Paul Hsieh
http://www.pobox.com/~qed/userInput.html
Nov 14 '05 #173
Paul Hsieh <qe*@pobox.co m> wrote:

Which kind of makes you wonder exactly what value the standard C library is
giving you. If this whole "ignore '\0'" feature of fgets() was a somehow
necessary or useful feature which one could easily map to a more general
solution there would be no issue. But its not.


You seem to have mistaken fgets() for a general-purpose input function.
It's not. It's intended to read lines from a text file. Text files
don't contain NULs. If you want to read arbitrary data and know for
sure how much you've read, use fread.

-Larry Jones

I'm a genius. -- Calvin
Nov 14 '05 #174
In article <fo************ @jones.homeip.n et>, la************@ eds.com says...
Paul Hsieh <qe*@pobox.co m> wrote:
Which kind of makes you wonder exactly what value the standard C library is
giving you. If this whole "ignore '\0'" feature of fgets() was a somehow
necessary or useful feature which one could easily map to a more general
solution there would be no issue. But its not.
You seem to have mistaken fgets() for a general-purpose input function.


Yes, just as I have mistaken the C language for a general purpose programming
language, and the standard library to be something which abstracts the machine
into useful primitives.

But its not just me. When a programmer wants input, they don't want to learn
about why fgets() ignores '\0' or why they have to write a convoluted loop over
malloced memory that still does it wrong.

Its not like having a good, reasonable performing, useful, consistent and
generic semantic was out of the reach of the people inventing this digital
diarrhea:

http://www.pobox.com/~qed/userInput.html
It's not. It's intended to read lines from a text file. Text files
don't contain NULs.
And this is enforced by what part of the standard? Is putting a '\0' into a
"text file" singled out as causing UB in the standard?
[...] If you want to read arbitrary data and know for sure how much you've
read, use fread.


Well there's a real valuable suggestion if ever I've heard one.

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/
Nov 14 '05 #175

On Sat, 13 Dec 2003, Paul Hsieh wrote:

In article <3F************ ***@yahoo.com>, cb********@yaho o.com says...
Paul Hsieh wrote:
... snip ...
In short, fgets() does not leave you with a deterministic way of
knowing how much data was really read unless you outlaw '\0' from
the input stream.


IF this is a potential problem, you are allowed to build your
input around fgetc, getc, or even getchar.


Which kind of makes you wonder exactly what value the standard C library is
giving you. If this whole "ignore '\0'" feature of fgets() was a somehow
necessary or useful feature which one could easily map to a more general
solution there would be no issue. But its not.


Maybe you think you've already explained what you mean elsethread,
but would you take the time again, please, to explain (1) what you
mean by "ignore '\0'" in the context of fgets(); and (2) why you
consider this (whatever it is) a problem in the context of C
programming? (I certainly don't understand what your reply to
CBFalconer means -- what do you mean by "map to a more general solution,"
particularly?)

In the interest of shortening this subthread, I will explain what
*I* think you mean by (1), and why (1) is not a problem in C.

fgets() reads characters input from a file until it hits either
'\n' or EOF, and stores these characters into a buffer. When fgets()
is done reading (having hit either '\n' or EOF), it terminates the
buffer with '\0', thus making a string that it returns to the user.
(It also stops reading input when so-and-so many characters have
been read, but that's irrelevant to what I think you're discussing.)
This behavior is perfectly good for dealing with text streams,
but can fail in the following way when used on binary streams:
Suppose the input stream contains a '\0' byte. fgets() reads that
byte, sees that it is not '\n' (and that no EOF condition has been
raised), and stores it in the buffer. Then it proceeds, reading
and storing characters until '\n' or EOF.
So, if the user sees that his buffer contains a string that's
not terminated with '\n', he is unsure of whether the terminating
'\0' is due to EOF in the stream, or the actual reading of a '\0'
byte. He can check feof() to find out whether the stream *is*
at EOF, but there still remains the possibility that the stream
hit EOF after reading one or more '\0's.

So the problem is not that fgets() "ignores" null characters in
the input stream; it's rather that fgets() does *not* perform any
special operations when confronted with one. Which is perfectly
reasonable, since text streams do not contain '\0', and binary
streams assign no interesting semantics to '\n' characters (or
sequences). That is, it is /a priori/ a silly idea to use fgets()
in any situation in which the above-mentioned ambiguity could
arise.
Even if a (possibly malicious) text stream *did* contain a
'\0' byte, how could fgets() possibly deal reasonably with it?
It couldn't treat it as a normal character, because that would
be ambiguous. It couldn't treat it as '\n', because that would
break the existing semantics of fgets(), which guarantee that
each complete line read end with the terminating '\n' (although
this might be the best "solution" behavior). And it couldn't
use any kind of escape sequence to represent '\0', because all
other bytes already have unambiguous semantics in the output
of fgets().

The solution, in a C-programming context, is to use fgets()
only on text streams, and on binary streams to use fread(), getc(),
or other functions that treat all bytes symmetrically (i.e., with
no special semantics involving '\n', '\0', or whitespace).
You have implied elsethread that you think this solution a
"non-solution" (or perhaps I'm again imagining sarcasm where
none was intended). If that's the case, would you mind explaining
what you think is wrong with getc() and fread() on binary streams?

-Arthur
Nov 14 '05 #176
Paul Hsieh <qe*@pobox.co m> wrote [quoting me]:

But its not just me. When a programmer wants input, they don't want to learn
about why fgets() ignores '\0' or why they have to write a convoluted loop over
malloced memory that still does it wrong.


fgets does *not* ignore NULs, it reads them and stores them in the
buffer just as you'd expect. The "problem", if there is one, is that it
returns a string and C strings cannot contain NULs. That's not fgets's
fault, it the natural result of a design choice. Different string
representations have different plusses and minuses; nothing's perfect,
not even your suggested replacement.
It's not. It's intended to read lines from a text file. Text files
don't contain NULs.


And this is enforced by what part of the standard? Is putting a '\0' into a
"text file" singled out as causing UB in the standard?


No, but 7.19.2 makes it clear that there are many limitations to what a
text stream can portably contain. In all my years of programming, I
don't think I've ever needed to read lines of text that could contain
NULs. And for most of those years, I've known that if I did, I should
use getc to do so, not fgets.
[...] If you want to read arbitrary data and know for sure how much you've
read, use fread.


Well there's a real valuable suggestion if ever I've heard one.


Are you similarly dismissive of people who tell you to use a screwdriver
for driving screws rather than a hammer? If you insist on using the
wrong tool for the job, it's more than a little disingenuous to complain
about how badly designed it is.

-Larry Jones

When I want an editorial, I'll ASK for it! -- Calvin
Nov 14 '05 #177
On Sun, 14 Dec 2003 03:12:55 GMT, in comp.lang.c , qe*@pobox.com (Paul
Hsieh) wrote:
But its not just me.
Nor is it every programmer.
When a programmer wants input, they don't want to learn
about why fgets() ignores '\0' or why they have to write a convoluted loop over
malloced memory that still does it wrong.
*shrug*. You're right, but irrelevant. Every language has foibles, and
every programmer has to learn to live with them. You don't like C's
malloc? Use a different general purpose language. You don't like the
way that << works in C++? Choose Basic.
Its not like having a good, reasonable performing, useful, consistent and
generic semantic was out of the reach of the people inventing this digital
diarrhea:


Yeah, well you're designing an all singing-all dancing line reader. I
rarely if ever need that and so fgets() generally work just fine
without putting in all that dihorrea.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.angelfire.c om/ms3/bchambless0/welcome_to_clc. html>
----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
Nov 14 '05 #178
aj*@nospam.andr ew.cmu.edu says...
[...] You have implied elsethread that you think this solution a
"non-solution" (or perhaps I'm again imagining sarcasm where
none was intended). If that's the case, would you mind explaining
what you think is wrong with getc() and fread() on binary streams?


getc() only reads a character (i.e., it reads too little), and fread() only
reads a buffer and ignores line terminators (i.e., it reads too much). That
leaves writing a loop over getc() as the only solution. But then one has to
wonder, why was fgets() included with its specific semantics, if its really
just a subset of a more general solution?

fgets() is the only string function which specifically ignores '\0'. A minor
change in its semantics would have made it more consistent with the rest of the
C language without any restriction of the file mode (return the length,
terminate on either '\0' or '\n' but always add an additional '\0' at the end)
which would have made it a *superset* of what we have today without any strange
conditions or anomolies.

The value of a library function should be how much it *saves* the programmer
from having to code themselves. In the context of the C language, you might
also have other criteria like being minimal, but I don't see that it would be
significantly larger to have implemented fgets with the semantics I suggest.

--
Paul Hsieh
http://www.pobox.com/~qed/userInput.html
Nov 14 '05 #179
On Mon, 15 Dec 2003 03:50:21 GMT,
Paul Hsieh <qe*@pobox.co m> wrote:
aj*@nospam.andr ew.cmu.edu says...
[...] You have implied elsethread that you think this solution a
"non-solution" (or perhaps I'm again imagining sarcasm where
none was intended). If that's the case, would you mind explaining
what you think is wrong with getc() and fread() on binary streams?
getc() only reads a character (i.e., it reads too little), and
fread() only reads a buffer and ignores line terminators (i.e., it
reads too much). That leaves writing a loop over getc() as the only
solution. But then one has to wonder, why was fgets() included with
its specific semantics, if its really just a subset of a more
general solution?


fgets was designed to read text lines into a string. A string, in C,
is a bunch of characters, terminated by a '\0'.
fgets() is the only string function which specifically ignores '\0'.
I haven't been able to find a post yet in which you specify exactly
what you mean by "ignores '\0'". Other people have already explained
that fgets() does not ignore embedded null characters in text files.
It neatly reads it in, and puts it in the buffer nominated. When you
then go ahead, and treat that buffer as a string, the first zero in
there will terminate the string, as the C language requires. The rest
of the stuff in the buffer just never is visible if you look at it as
a string.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#define MAXLEN 40

int main(void)
{
char buf[MAXLEN];

while (fgets(buf, MAXLEN, stdin))
{
size_t length = strlen(buf);
int i = 0;
while (i < MAXLEN && buf[i] != '\n')
i++;
if (i == MAXLEN)
puts("No newline found");
else
printf("Found newline at %d\n", i);

printf("READ %d: %s", (int)length, buf);
if ( i != (int)length - 1)
putchar('\n');
}
return 0;
}

If you compile and run the above and feed it a "text" file with
embedded null characters on stdin, you'll notice that fgets() does not
"ignore" the null characters, and neither does it stop reading on a
null character. It merrily continues until the end of line, end of
file, an error condition, or until the buffer is full. As per
specification.

You'll also notice that the embedded null characters "confuse" tools
like strlen() and %s in printf(), because they (correctly) assume that
the first null character is the end of the string.
A minor change in its semantics would have made it more consistent
with the rest of the C language without any restriction of the file
mode (return the length, terminate on either '\0' or '\n' but always
add an additional '\0' at the end) which would have made it a
*superset* of what we have today without any strange
conditions or anomolies.
There are no anomalies. fgets() was meant to read text into a string.
If you want embedded '\0' characters, it is no longer a string (or
rather, the string ends where the first zero appears). If you want to
work with buffers that have zeroes in them, it is no longer a string,
and fgets isn't the right tool.
The value of a library function should be how much it *saves* the
programmer from having to code themselves. In the context of the C
language, you might also have other criteria like being minimal, but
I don't see that it would be significantly larger to have
implemented fgets with the semantics I suggest.


Well, Dennis Ritchie didn't implement fgets() with the semantics you
suggest, so fgets() as it is, is what we got. If you feel that another
function with other semantics is needed, you should probably take it
up with the folks in comp.std.c.

But none of that means that fgets() "ignores" '\0' characters.

What you seem to be saying instead is that you want fgets() to have a
different interface, and you probably should just get over that,
because it isn't going to happen.
I'd probably find it more fruitful to argue that the standard
explicitly uses the word "string" in the description for fgets(), to
avoid this sort of pointless argument.
Martien
--
|
Martien Verbruggen |
Trading Post Australia | "Mr Kaplan. Paging Mr Kaplan..."
|
Nov 14 '05 #180

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
3456
by: Anthony Martin | last post by:
I've been reading the Java Language Specification, and in Chapter 16 there's an interesting topic called Definite Assignment. http://tinyurl.com/3fqk8 I'm wondering about the idea of "Deferred Final Automatic Variables" like the following: void unflow(boolean flag) { final int k;
14
23153
by: Medi Montaseri | last post by:
Hi, I think my problem is indeed "how to implement something like java's final in C++" The long version.... I have an abstract base class which is inherited by several concrete classes. I have a group of methods that I'd like to implement in the base class
48
8734
by: David J Patrick | last post by:
I'm trying to rewrite the CSS used in http://s92415866.onlinehome.us/files/ScreenplayCSSv2.html. using the w3.org paged media standards as described at http://www.w3.org/TR/REC-CSS2/page.html The ScreenplayCSS is flawed, for several reasons; -overuse of <div id= tags -doesn't scale screen resolutions (convert from px to in, pt ?) -no media="print" (how much coule be shared between "screen" & "print") -no automatic page breaks (with...
10
5126
by: Bezalel Bareli | last post by:
I know I have seen some threads on the subject long time ago and it was using a virtual base class ... in short, what is the nicest way to implement the Java final class in c++ Thanks.
14
1780
by: My4thPersonality | last post by:
Has the fact that both Java and C# are garbage collected, and C++ in not, anything to do with the fact that there is no language item to prevent a class from being inherired from? I once read that Java and C# implement this feature for preformance, but the C++ creators said it was not worse the effort. So because Java and C# are garbage collected, in their case is it worse the effort? What is the connection?
1
8625
by: silverburgh.meryl | last post by:
I am trying to convert this code from java to c++: public final class Type { public static final int DEFAULT = 1; private static int index = 2; public static final int COLUMN1 = (int) Math.pow(2, index++); public static final int COLUMN2 = (int) Math.pow(2, index++); public static final int COLUMN3 = (int) Math.pow(2, index++); public static final int COLUMN4 = (int) Math.pow(2, index++);
5
1403
by: Anthony Baxter | last post by:
On behalf of the Python development team and the Python community, I'm happy to announce the release of Python 2.4.3 (final). Python 2.4.3 is a bug-fix release. See the release notes at the website (also available as Misc/NEWS in the source distribution) for details of the more than 50 bugs squished in this release, including a number found by the Coverity Scan project. Assuming no major bugs pop up, the next release of Python will be...
14
3004
by: Rahul | last post by:
Hi Everyone, I was searching for final class in c++, and i came across few links which suggests to have the constructor of the, to be final class, as private so that any derived class's constructors can't access the same. class C { private:
1
1710
by: Rajib | last post by:
Not that this serves any real purpose, but gcc allows me to do some hack like this: class hide_A { public: class A { public: virtual int final() { return 42; } };
0
9810
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
11207
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10794
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10443
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
8000
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7153
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5830
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4652
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3259
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.