some well known stupidness in c99

G

glen herrmannsfeldt

BartC said:
the question is how syntax to choose to distinguish between
pointers-to-one and pointers-to-many in such cases:
void print(char* text) //pointer to undefined many
{
}
void print(char(1)* text) //pointer to one ?
{
}
also think sometimes (like here) if java-like
syntax wouldnt be clearer
char a; //a is adress to one
char[] a; //a is adress to undefined many
char[16] a; //a is adress to chunk of 16 chars

If you want to call them addreses, you need to be careful as
to what is constant and what isn't.

In the first case, &a is a constant. In the third case,
I am not so sure, but a would be for char a[16];
In my opinion, C type syntax is broken. And that's not just the convoluted
syntax.
It's because char[] means different things in different contexts: an array
in some places, and a pointer in another:
char a[]={65,66,67}; // array
void fn (char[] a); // pointer

Not quite as many meanings as the word "static", though.
char[] meaning array would be illegal in a parameter context, but instead of
leaving that hole in the 'map' of possible types, everything moves up one
instead! The penchant for C to gloss over any dereferences needed - or not
needed - to index an array/pointer, just confuses things further.

I believe that some think that the function argument [] was a mistake,
though I sort of like it. (Not that I usually use it.)

The array case could have been done something like char a[*]={65,66,67};
indicating that there is an unknown length.
I think you have your work cut out...

-- glen
 
F

fir

W dniu wtorek, 20 listopada 2012 16:47:22 UTC+1 użytkownik Bart napisał:
W dniu wtorek, 20 listopada 2012 13:52:40 UTC+1 użytkownik Ben Bacarisse
napisał:


Nicer than what? As it happens, 'int[10]' is the type name


I mean that this way of array definition seem
to be better (than present)
int t[100]; <- worse
int[100] t; <- better



Have a look at some other languages. For example the D programming language

(dlang.org), which has tidied up the language quite a bit, and uses your

syntax for arrays. It might give some ideas.



(However I don't think it's gone quite far enough. That array would be

declared, in another language I use, as:



[100]int t



this uses a consistent left-to-right syntax which matches the descriptionof

the type in English.)

I ve done overview of D also, It is ok, but
my own improvements goes much different way

my c2 goes much to modular programming, also
polishes the surface (as here with lenghtof
and arrays or default passing by implicit
pointers in calls)

void foo(Some s) //s struct by implicit adres
{
s.x = 0;
}

, also posiibly operators
in "c = a (dot) b;" form, realloc mechanism
(keyword) for arrays, possibly binding soma
call contexts as in

void f()
{
for(;;)
{
char c = getchar("file.txt");

if(eof) //eofand error are wariables
break; // form getchar contex
if(error) // possibly statics of getchar
break;
}

}


float4 internal type (for sse accelerated
operations), many returned values

(int x, int y ) foo( int a, int b)
{

}

any binary data for min input output,
ad hoc enums (ad hoc enum values with no definietion
very convenient do_something(10,10,'quick') //'quick'
would be ad hoc enum)

and more - it is long list as to today already
but still searching for improvements

(so tnx for supporting it and bringing all the
possible source of concepts, it is welcome, though
really all of them on my own list was of my own thinking
and as today not even one was taken from reading
something external )

(fir)
 
F

fir

W dniu wtorek, 20 listopada 2012 18:08:07 UTC+1 użytkownik Kenneth Brody napisał:
W dniu poniedziałek, 19 listopada 2012 20:10:29 UTC+1 użytkownik Greg Martin napisał:
On 12-11-19 09:42 AM, fir wrote:

W dniu poniedziałek, 19 listopada 2012 18:31:24 UTC+1 użytkownik James Kuyper napisał:



Note: there are only three values you can pass to exit() with behavior
that is defined by the C standard: EXIT_SUCCESS, EXIT_FAILURE, and 0..
The meanings of -1 or 13 can be different for different implementations
of C.

I would like to return whole string to system not just number (In general way maybe even any kind of data, I was sayin that few week ago,
here I just used it as an argument that clever
improvements ale welcome - so there is point
of inventing and also talking about them )
[...]

(answer also to James Kuyper couse it is about the same thing) I just think that returning a
string (or possibly maybe even accepting any binary data thru input andoutput) will be
better and more informative. OS could do
everything he wants, possibly print it out
in console or send it as an input to other c program (it is much unix like in good way)
It is good idea imo.

for example i would like much more return an
"could not find SSE processor" "OPENGL card not found" "SUCCES" "Compilation ok" "20:21:22 12-11-2012" or such like, than -1 or 0, 1, or 13 exit codes



But, given that Windows, Unix, Linux, FreeBSD, and just about any other O/S

you are likely to run into, all permit a single integer (sometimes only 7

bits, in fact) to be "returned", how do you propose to return a string to

the O/S?



The best you can hope for is a replacement for "exit(int)", such as

"my_exit(char *,int)", which displays the string, and then returns the

specified exit code to the O/S.

systems could be rewritten :O Iam spiking here
about 'technical goodnes' what would be good
(better then present)
it is not about exit("some string") but its
about, some like

char* main(char*)
{
return "halo world";
}

kool imo
 
J

James Kuyper

W dniu wtorek, 20 listopada 2012 18:08:07 UTC+1 użytkownik Kenneth Brody napisał: ....
systems could be rewritten :O. ...

No, they cannot; at least, not by the C committee. It doesn't have that
authority. Only operating system designers have that authority (and if
they exercised that authority, it could easily break the vast majority
of existing programs). Those designers appear to have almost universally
disagreed with you on this issue. Even if you're right, they're not
likely to change their minds any time soon, and the chance that the
overwhelming majority of them will adopt your idea is vanishingly small
for the foreseeable future. Without that overwhelming majority, it
doesn't make sense for the C standard to adopt your idea.

So long as it is the goal of the C committee to define C in such a way
that it can in fact be implemented "almost everywhere", the definition
of C will have to cope with the fact that virtually every system that
has a concept of an exit status, uses an integer of some kind for that
status, and (almost?) none of them uses a text string for that purpose.
... Iam spiking here
about 'technical goodnes' what would be good
(better then present)
it is not about exit("some string") but its
about, some like

char* main(char*)
{
return "halo world";
}

The standard currently allows an implementation to accept such code. If
anybody ever decides to design an operating system that's compatible
with your concept, it would be entirely reasonable for an implementation
targeted for that operating system to do so. However, so long as the
overwhelming majority of existing operating systems accept only integers
as exit statuses, and not strings, the C standard can NOT mandate
acceptance of such code; not unless you're willing to address the issue
of what it should do when compiled for an operating system that doesn't
accept strings.
 
G

glen herrmannsfeldt

No, they cannot; at least, not by the C committee. It doesn't have that
authority. Only operating system designers have that authority (and if
they exercised that authority, it could easily break the vast majority
of existing programs). Those designers appear to have almost universally
disagreed with you on this issue. Even if you're right, they're not
likely to change their minds any time soon, and the chance that the
overwhelming majority of them will adopt your idea is vanishingly small
for the foreseeable future. Without that overwhelming majority, it
doesn't make sense for the C standard to adopt your idea.

Note that Fortran allows one to specify either a numeric or
string value on the STOP statement. That hasn't stopped implementations
on systems that didn't support string status values.
So long as it is the goal of the C committee to define C in such a way
that it can in fact be implemented "almost everywhere", the definition
of C will have to cope with the fact that virtually every system that
has a concept of an exit status, uses an integer of some kind for that
status, and (almost?) none of them uses a text string for that purpose.

I am sure that the Fortran committee feels the same way.

The usual implementation, for either numeric or string value,
is to print it on along with the program output. Recent Fortran
has an ERROR_UNIT, what unix calls stderr.

Now, I know that people have complained about the value being
printed, either numeric or string, but it is part of the standard.

Some things are easier to work around than others, and standards
usually allow for such things.

-- glen
 
K

Keith Thompson

I wrote the above. When you post a followup, whatever interface
you're using (Google Groups in your case) adds an attribution line,
indicating who wrote the quoted text. Please don't delete that line.
It makes it much easier to follow the discussion.
I do like c in very much extent so it sound
totaly fantastic (not real( to me, I use
called it stupidness becouse I was/am real
angry/mad to know that I cannot use const int
in c99 and finding also explanation sort of 'consyt int x doeas not mean that x is const'
(and the fact that i can throw c compilers to trashbin)
I feel i can call it stupidnees though some
explanations what do I mean would be required
- I said what do I meant :(

"const int x;" certainly does mean that x is const. It doesn't mean
that x is *constant*.

The problem (and I agree that it's a problem) is that "const" doesn't
mean "constant". It means "read-only". As such, it works exactly the
way it's supposed to.

So as I see it, there are two problems here, neither of them horrible.

First, the "const" keyword would cause less confusion if it were spelled
"readonly". It could work exactly the way it works now, and it wouldn't
raise the expectation that a readonly object can be used as a constant
expression.

Second, there's no way (other than enum and #define, both of which have
their problems) to define an identifier that can be used as a constant
expression.

We don't have the luxury of redefining the language and breaking
existing code, but if we did, I'd suggest the following (among many
other things):

1. Change the "const" keyword to "readonly".

2. Add a "constant" keyword, allowing you to define things like:

constant int x = 42;

constant int y = 1.0/3.0; /* not exactly representable,
but still constant */

constant char ESC = '\x1b';

A "constant" declaration does not create an object; no storage is
allocated for it, and it has no address. The defined identifier
can be used as a constant expression of the specified type, with
the value of the initializer. The initializer must be a constant
expression. The type must be a scalar type; I haven't thought about
the semantics for pointer types, but "const void *nullptr = NULL;"
would be permitted and useful.

I would *not* suggest having both "const" and "constant" as keywords;
that would be too confusing. Though I suppose the committee could
add a "constant" keyword, as described above, without breaking
anything other than code that uses "constant" as an identifier
(or adding a "_Constant" keyword and a <stdconstant.h> header with
"#define constant _Constant").

As for the current lack of this feature, I'd say you've already
made your point.
 
K

Keith Thompson

BartC said:
Apparently 'separate compilation' can involve hard-coding a constant
imported from a 3rd-party header, which needs to be repeated when that
header is updated.

That, according to you, is completely different from hard-coding a constant
imported from a header (3rd party or otherwise), if that header includes
some automatically gleaned content. (Although for all we know, windows.h is
also partly generated with tools we don't know about, extracting global data
in the manner I've suggested.)

I have no problem with an automated tool that generates a .h file
from information in a .c file. It does create a dependency on
that .c file, but that's created by the build environment, not by
the language.

But if you add a language feature that creates such a dependency,
then you break C's concept of separate compilation.

If I have a library implemented by source files foo.h and foo.c, and I
want to write a program that uses that library, all I need is foo.h and
foo.o. I can compile my main.c that has `#include "foo.h"`, and I can
link with foo.o, and I never need to see a copy of foo.c.

Breaking that model is not an option.
 
G

glen herrmannsfeldt

I wrote the above. When you post a followup, whatever interface
you're using (Google Groups in your case) adds an attribution line,
indicating who wrote the quoted text. Please don't delete that line.
It makes it much easier to follow the discussion.
(snip)

"const int x;" certainly does mean that x is const.
It doesn't mean that x is *constant*.

C does give words funny meanings sometimes, my old favorite
being "static" which has about five meanings.
The problem (and I agree that it's a problem) is that "const" doesn't
mean "constant". It means "read-only". As such, it works exactly the
way it's supposed to.
So as I see it, there are two problems here, neither of them horrible.
First, the "const" keyword would cause less confusion if it were spelled
"readonly". It could work exactly the way it works now, and it wouldn't
raise the expectation that a readonly object can be used as a constant
expression.
Second, there's no way (other than enum and #define, both of which have
their problems) to define an identifier that can be used as a constant
expression.

Hmm. Java has static final where you need compile time constants.

Does C already have a meaning for static const?

Fortran has PARAMETER, I believe tracing back to some DEC compilers
from years ago. For a long time, Fortran didn't allow for constant
expressions. You couldn't dimension an array 2+2, but only 4.
There are some macro processors that will evaluate constant
expressions for languages that don't.
We don't have the luxury of redefining the language and breaking
existing code, but if we did, I'd suggest the following (among many
other things):
1. Change the "const" keyword to "readonly".
2. Add a "constant" keyword, allowing you to define things like:
constant int x = 42;
constant int y = 1.0/3.0; /* not exactly representable,
but still constant */
constant char ESC = '\x1b';
A "constant" declaration does not create an object; no storage is
allocated for it, and it has no address. The defined identifier
can be used as a constant expression of the specified type, with
the value of the initializer. The initializer must be a constant
expression. The type must be a scalar type; I haven't thought about
the semantics for pointer types, but "const void *nullptr = NULL;"
would be permitted and useful.

I don't know that storage can't (couldn't) be allocated, but yes,
it seems likely that one couldn't have a pointer to one, as one
can't to other constants.

At least some systems would allow for constant pointers to
static data. (What OS/360 calls address constants, resolved
by the linker, and then relocated by program fetch.)
I would *not* suggest having both "const" and "constant" as keywords;
that would be too confusing. Though I suppose the committee could
add a "constant" keyword, as described above, without breaking
anything other than code that uses "constant" as an identifier
(or adding a "_Constant" keyword and a <stdconstant.h> header with
"#define constant _Constant").
As for the current lack of this feature, I'd say you've already
made your point.

-- glen
 
I

Ian Collins

The problem (and I agree that it's a problem) is that "const" doesn't
mean "constant". It means "read-only". As such, it works exactly the
way it's supposed to.

So as I see it, there are two problems here, neither of them horrible.

First, the "const" keyword would cause less confusion if it were spelled
"readonly". It could work exactly the way it works now, and it wouldn't
raise the expectation that a readonly object can be used as a constant
expression.

Second, there's no way (other than enum and #define, both of which have
their problems) to define an identifier that can be used as a constant
expression.

We don't have the luxury of redefining the language and breaking
existing code, but if we did, I'd suggest the following (among many
other things):

1. Change the "const" keyword to "readonly".

2. Add a "constant" keyword, allowing you to define things like:

constant int x = 42;

constant int y = 1.0/3.0; /* not exactly representable,
but still constant */

constant char ESC = '\x1b';

Or just adopt the C++ rules and avoid breaking any valid existing code!
 
J

James Kuyper

On 11/20/2012 04:14 PM, glen herrmannsfeldt wrote:
....
Note that Fortran allows one to specify either a numeric or
string value on the STOP statement. That hasn't stopped implementations
on systems that didn't support string status values.

Yes, and the Fortran specifies what it does with that string: it
displays it, rather than attempting to pass it as an exit status. I've
repeatedly asked fir to specify what he wanted done with the string
after it was returned, with no response. If he had said "print it to
stderr", that would be perfectly reasonable; but if so, he still needs
to specify what exit status should be returned, since he's hijacked what
used to be the only way of specifying that status.
 
J

James Kuyper

On 11/20/2012 04:27 PM, glen herrmannsfeldt wrote:
....
C does give words funny meanings sometimes, my old favorite
being "static" which has about five meanings.

Last time I looked, I only came up with three:
1. at block scope: static storage duration
2. at file scope: internal linkage
3. in the leading dimension of a pointer parameter of a function
declared as if it were an array, it renders the behavior undefined if
the function is passed a pointer argument that doesn't give access to an
array of at least the specified length.

What are the other two?

....
Does C already have a meaning for static const?

Yes, 2: "read-only static storage duration" and "read-only internal
linkage".
 
K

Keith Thompson

James Kuyper said:
On 11/20/2012 04:14 PM, glen herrmannsfeldt wrote:
...

Yes, and the Fortran specifies what it does with that string: it
displays it, rather than attempting to pass it as an exit status. I've
repeatedly asked fir to specify what he wanted done with the string
after it was returned, with no response. If he had said "print it to
stderr", that would be perfectly reasonable; but if so, he still needs
to specify what exit status should be returned, since he's hijacked what
used to be the only way of specifying that status.

Given that C already has perfectly good mechanisms for printing
messages to stderr, there's no point at all in changing the
definitions of main() and exit() to do the same thing.

There's nothing wrong with having a convenience function that prints
a message and terminates the program, but there's no need to define
such a function in the language.
 
J

James Kuyper

On 11/20/2012 04:57 PM, Keith Thompson wrote:
....
Given that C already has perfectly good mechanisms for printing
messages to stderr, there's no point at all in changing the
definitions of main() and exit() to do the same thing.

There's nothing wrong with having a convenience function that prints
a message and terminates the program, but there's no need to define
such a function in the language.

I was just trying to get fir to be more specific about what he was
proposing. I agree with you that if this is what he was proposing
(something he's never bothered clarifying, despite repeated requests),
it's not really necessary - in fact, I've already pointed out to him the
ease with which he could define such a function himself.
 
K

Keith Thompson

Keith Thompson said:
constant int x = 42;

constant int y = 1.0/3.0; /* not exactly representable,
but still constant */

Whoops, I meant "double" here.
constant char ESC = '\x1b';

Incidentally, the first would be equivalent to

enum { x = 42 };

If we wanted to add this as a language feature, perhaps we could enhance
the current hijacking of the enum, by allowing it to be typed;

int enum { x = 42 };

double enum { y = 1.0/3.0 };

char enum { ESC = '\x1b' };

"int" would still be the default type, so existing code would not be
broken.

I suppose you could even allow a tag:

double enum dbl { a = 1.0, b = 1.5, c = 2.0 };

making "enum dbl" a synonym for "double". Again, in the absence of a
type, enums would keep their current semantics, and this:

enum bad { a = 1.0, ... };

should probably remain invalid.

[...]
 
I

Ian Collins

On 11/20/2012 04:57 PM, Keith Thompson wrote:
...

I was just trying to get fir to be more specific about what he was
proposing. I agree with you that if this is what he was proposing
(something he's never bothered clarifying, despite repeated requests),
it's not really necessary - in fact, I've already pointed out to him the
ease with which he could define such a function himself.

Well what else to you expect form a troll? Have a look at his previous
threads here.
 
I

Ian Collins

Given that C already has perfectly good mechanisms for printing
messages to stderr, there's no point at all in changing the
definitions of main() and exit() to do the same thing.

There's nothing wrong with having a convenience function that prints
a message and terminates the program, but there's no need to define
such a function in the language.

It is also straightforward to run an application from another (or a
shell) that captures stderr and returns error message to the caller. I
do this in my own extended version of POSIX popen. So I agree, the
mechanism already exists in standard C.
 
G

glen herrmannsfeldt

(snip, someone wrote)
I have no problem with an automated tool that generates a .h file
from information in a .c file. It does create a dependency on
that .c file, but that's created by the build environment, not by
the language.
But if you add a language feature that creates such a dependency,
then you break C's concept of separate compilation.

I suppose, but it sounds a lot like the Fortran .MOD files, which
as far as I know don't break separate compilation. It does complicate
compilation, and dependency loops aren't allowed, but it is still
separate compilation.
If I have a library implemented by source files foo.h and foo.c, and I
want to write a program that uses that library, all I need is foo.h and
foo.o. I can compile my main.c that has `#include "foo.h"`, and I can
link with foo.o, and I never need to see a copy of foo.c.
Breaking that model is not an option.


-- glen
 
J

James Kuyper

On 11/21/12 11:01, James Kuyper wrote: .... ....
Well what else to you expect form a troll? Have a look at his previous
threads here.

I just did. I think you and Adam Wysocki may be right. I tried looking
at his pl.comp.lang.c posts that Adam referred to, but Google's
Polish->English translations aren't good enough for me to be sure of the
trollishness of his behavior in that group.
 
B

BartC

Keith Thompson said:
I have no problem with an automated tool that generates a .h file
from information in a .c file. It does create a dependency on
that .c file, but that's created by the build environment, not by
the language.

Finally someone seems to get what I'm talking about...
But if you add a language feature that creates such a dependency,
then you break C's concept of separate compilation.

But it needn't be an actual dependency on the source code of another module.
Let's take the example files used before: victim.c and file1.c (we don't
need file2.c).

victim.c makes use of resources in file1.c, and currently this is done by
creating a header file1.h. The compiler of victim.c doesn't need to see
file1.c, only file1.h.

My suggestion, if the concept of an 'import' statement was supported by the
language, could work the same way: the import statement could simply make
use of an 'exports' file called file1.h. The difference is that file1.h
might be generated automatically, by a separate process that does need
access to file1.c, but need have nothing to do with the compiler of
victim.c.

In fact, file1.c could be on the other side of the world (locked in a vault
below ground); all that's needed by the compiler of victim.c, is the public
exports file (eg. file1.h), which has been generated at some time in the
past.
If I have a library implemented by source files foo.h and foo.c, and I
want to write a program that uses that library, all I need is foo.h and
foo.o. I can compile my main.c that has `#include "foo.h"`, and I can
link with foo.o, and I never need to see a copy of foo.c.

Breaking that model is not an option.

As I've explained above, that model can stay largely the same. Actually we
don't even need a new 'import' statement (although it's a lot tidier); just
'include' will suffice. It boils down to whether the exported names in
file1.c (functions which are not static, file-scope variables which are not
static, and I would extend it to explicitly exported typedefs, enums and so
on) make their way into file1.h with the help of the language or not.
 
G

glen herrmannsfeldt

(snip)
The difference is that the latter, using compile-time constants, can (and
*must*, AFAIK) be picked up at compile time. In the former, using runtime
"constants", the clash *cannot* be detected until the code is executed, at
which point it's too late. (Though, I suppose, it might theoretically be
able to be caught at link time.)

The tradition of switch/case is that they be resolved at compile
time, but is that required?

Yes, link time is an extension of compile time, and some things could
be resolved at link time.

For a long time I have thought that the tradition of linkers was to
follow the requirements of Fortran, and for other languages to then
use those features.

(Though the pseudo-registers used by OS/360 PL/I compilers for global
data that is task local on multitasking systems, seems to have been
a special addition to the OS/360 linker.)

It is nice for compilers to optimize the switch statement in the
case where simple jump tables can be used. One could also imagine
a hash table being used, where the table is generated at link time
and loaded into the previously compiled object program.

Many years ago, I found that some expressions wouldn't work in
case statements, such as ones of the form: "abcd"[1].
So, even what seems to be a compile time constant might not
be in C terms.

-- glen
 

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
474,078
Messages
2,570,572
Members
47,204
Latest member
MalorieSte

Latest Threads

Top