By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,885 Members | 1,469 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,885 IT Pros & Developers. It's quick & easy.

Memory allocation for an initialized character pointer;

P: n/a
Hi all,

If I have a piece of code something like this

void main(void)
{
char * p1="abcdefghijklmn";
.............................................

}

For p1 and whatever it points to , where is the memory allocated. Is
it on heap or stack or
some other common global area. I am assuming it should be either on
stack or some global area. Unless
a user does a malloc storage space cannot be allocated on heap is my
assumption. Can someone
throw some light on how compilers do this.

What if the above piece of code is changed to something like

void main(void)
{
char *p1;
char a[20]="abcdefgh";

strcpy(p1,a);
}

Now where is the space allocated for p1 and whatever it points to
after strcpy.

Thanks in advance.

Regards,
Ar
Sep 30 '08 #1
Share this Question
Share on Google+
50 Replies


P: n/a
ar******@gmail.com writes:
If I have a piece of code something like this

void main(void)
{
char * p1="abcdefghijklmn";
.............................................

}
The correct declaration for main is "int main(void)". See the
comp.lang.c FAQ, <http://www.c-faq.com/>, questions 11.12a, 11.12b,
11.14a, 11.14b, and 11.15.
For p1 and whatever it points to , where is the memory allocated. Is
it on heap or stack or
some other common global area. I am assuming it should be either on
stack or some global area. Unless
a user does a malloc storage space cannot be allocated on heap is my
assumption. Can someone
throw some light on how compilers do this.
Storage for p1 itself (the pointer object) has what the standard calls
"automatic storage duration". That means it's created on entry to the
main function, and deallocated on exit from the main function. On a
typical system, it will be allocated on the "stack", but
implementations are allowed to use whatever mechanism meets the
standard's requirements.

Storage for the string literal, "abcdefghijklmn" plus the terminating
'\0' character, has "static storage duration". This storage exists
for the entire lifetime of the program. Again, implementations are
allowed to use whatever mechanism meets the standard's requirements.
What if the above piece of code is changed to something like

void main(void)
{
char *p1;
char a[20]="abcdefgh";

strcpy(p1,a);
}
p1 and a (a pointer object and an array object) have "automatic
storage duration"; in a typical implementation, they'll be stored on
the "stack" (but see above). Notionally, the contents of the string
literal are stored somewhere with static storage duration, but since
it's used only to initialize a, the compiler doesn't actually need to
keep it around.

But the strcpy() call will most likely fail. It attempts to copy 8
bytes ("abcdefg" plus the trailing '\0') to whatever memory p1 points
to, but you haven't allocated any memory for p1 to point to. It might
appear to work correctly, it might terminate your program with an
error message (if you're lucky), or it might clobber some critical
piece of memory and cause arbitrarily bad things to happen, limited
only by whatever safeguards are imposed by your operating system.
This is what the standard calls "undefined behavior".

You could allocate memory using malloc():

p1 = malloc(strlen(a) + 1);
if (p1 == NULL) {
/* malloc failed, handle the error somehow */
}
else {
strcpy(p1, a); /* p1 now points to a copy of the string */
}

[...]

Many questions like this can be answered by checking the comp.lang.c
FAQ (URL above).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 30 '08 #2

P: n/a
aruna...@gmail.com wrote:
Hi all,

If I have a piece of code something like this

void main(void)
'void' is not a legal return type for main(), though many compilers do
their users a disservice by allowing it. Change it to int, and add a
corresponding 'return' statement down below.
{
char * p1="abcdefghijklmn";
.............................................

}

For p1 and whatever it points to , where is the memory allocated. Is
it on heap or stack or
some other common global area. I am assuming it should be either on
stack or some global area. Unless
a user does a malloc storage space cannot be allocated on heap is my
assumption. Can someone
throw some light on how compilers do this.
The memory is statically allocated. The result is roughly equivalent
to writing

int main(void)
{
static const char some_name[] = {'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', '\0'};
char *p1 = (char*)some_name;

The actual location for such static memory is up to your compiler. As
usual, Twink has given you an answer that might be relevant to your
particular compiler, or it might be complete nonsense. The only way to
know for sure is to check your compilers' documentation, which would
have been a better answer than the one Twink gave you.
What if the above piece of code is changed to something like

void main(void)
{
char *p1;
char a[20]="abcdefgh";

strcpy(p1,a);
}

Now where is the space allocated for p1 and whatever it points to
after strcpy.
String literals are treated differently when they initialize char*
pointers than they are when they initialize char arrays. In the first
case, static memory is allocated for the contents of the string
literal, and the pointer is initialized with a value that points to
the first character of the array. It is not safe to attempt to write
to that array.

In the second case, the contents of the string literal are used to
directly initialize the declared array; no separate storage is
allocated. Whether or not the memory has static storage duration or
automatic storage duration depends upon the declaration of the array;
the same is true about whether or not the array is declared as
'const'.

In this case, both p1 and a are both allocated as memory with
automatic storage duration, which usually, but not necessarily, means
that it is allocated from a hardware stack. You'll need to check your
compiler's documentation to find out exactly how this is handled.

Each time a statement block is entered, objects defined in that block
with automatic storage duration need to be re-initialized. This isn't
an issue for your program, because it contains only one block which is
never reentered; the only such objects in your program could be
handled the same way as static memory, without causing any problems.
However, in the more general case this means that the information
needed to re-initialize the object each time the block is entered must
be stored somewhere else. The standard says nothing about how this
information is stored, and there are many different ways to do it. For
small objects, the data might even be stored as part of the
initialization instructions, rather than in a seperate block of
memory.

Now we come to the nasty part. p1 is uninitialized before the call to
strcpy(). As a result, the behavior of your program is undefined. In
principle, even attempting to read the value of p1 might make your
program abort, and there have been real machines where that would have
happened. In practice, what is likely to happen is that p1 contains a
bit pattern about which you know nothing, including whether or not it
represents a valid memory location. That pattern will be interpreted
as if it did represent a pointer, and that pointer value will be
passed to strcpy(). strcpy() will attempt to copy the string located
in 'a' to this unknown memory location. The consequences of doing so
could be catastrophic; on systems with poor memory protection, like MS/
DOS, it was actually possible to damage devices with a write to the
wrong memory location; it was certainly easy to mess up the
configuration of your computer, requiring at least a reboot. On more
modern OSs (a category that includes many OSs that predate MS/DOS by
decades), such code is like to produce a memory segment violation,
which will halt your program. If it doesn't halt, that means that p1
happens to point at a memory location that your program actually has
permission to write to, such as &p1. However, this will be an
unpredictable part of the memory allocated to your program, which
stands a good chance of making some other unpredictable part of your
program fail.

In short: NEVER use the value of an uninitialized variable; be
particularly careful about uninitialized pointer variables. You should
make sure that p1 points at something before you ask strcpy() to copy
something to the location p1 points at. You should also make sure that
whatever p1 points at, it is big enough to store the thing that you're
copying to it.
Sep 30 '08 #3

P: n/a
On Sep 30, 2:46*pm, Keith Thompson <ks***@mib.orgwrote:
ar******@gmail.com writes:
If I have a piece of code something like this
void main(void)
{
* *char * p1="abcdefghijklmn";
* * .............................................
}

The correct declaration for main is "int main(void)".
But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:

<quote>
5.1.2.2.1 Program startup

1 The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent;9) or in some other implementation-defined manner.

<end quote>

Thus, the prototype shown by the OP is also correct.

Sebastian

Sep 30 '08 #4

P: n/a
s0****@gmail.com writes:
On Sep 30, 2:46*pm, Keith Thompson <ks***@mib.orgwrote:
>ar******@gmail.com writes:
If I have a piece of code something like this
void main(void)
{
* *char * p1="abcdefghijklmn";
* * .............................................
}

The correct declaration for main is "int main(void)".

But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:

<quote>
5.1.2.2.1 Program startup
[snip]
or equivalent;9) or in some other implementation-defined manner.

<end quote>

Thus, the prototype shown by the OP is also correct.
That depends on what you mean by "correct". And no, I'm not playing
word games; it really does depend on what you mean by "correct".

An implementation is allowed, but not required, to support "void
main(void)". (In fact, this is covered by the general permission to
support extensions; the "or in some other implementation-defined
manner" wording in 5.1.2.2.1 is redundant.)

So if the OP's particular implementation, for whatever reason,
supports "void main(void)" -- which means that it must *document* it,
not just accidentally fail to reject it -- then "void main(void)" is
arguably correct *for that implementation*. But it's not portable; it
can be rejected, or can cause undefined behavior, on any
implementation that doesn't choose to support it. For example, the
status code returned to the environment when the program terminates is
normally the int value returned from main(), or passed to exit(). If
main() doesn't return an int value, what status code does the
environment see? The standard certainly doesn't say; the
implementation may or may not document it.

And there is absolutely no advantage to using "void main(void)" rather
than "int main(void)". You give up portability for the sake of
.... what exactly do you gain? Well, you can omit the "return 0;" or
"exit(EXIT_SUCCESS);" at the end of main() -- but C99 lets you omit
that anyway.

So yes, "void main(void)" can be "correct" in some narrow
circumstances. Or it can be incorrect.

But "int main(void)" is unquestionably correct. (Assuming, of course,
that you're using a C89 or better compiler that recognizes the "void"
keyword in this context -- but "void main(void)" is certainly no
better in that case.)

The above assumes a hosted implementation. In a freestanding
implementation (very loosely, an embedded system), "int main(void)"
might not be valid. But it's safe to assume that the OP is using a
hosted implementation.

(Cue the trolls whining that the correct declaration of main is the
only thing we discuss here.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 30 '08 #5

P: n/a
On Sep 30, 11:35 pm, s0s...@gmail.com wrote:
On Sep 30, 2:46 pm, Keith Thompson <ks...@mib.orgwrote:
aruna...@gmail.com writes:
If I have a piece of code something like this
void main(void)
{
char * p1="abcdefghijklmn";
.............................................
}
The correct declaration for main is "int main(void)".

But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:

<quote>
5.1.2.2.1 Program startup

1 The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent;9) or in some other implementation-defined manner.

<end quote>

Thus, the prototype shown by the OP is also correct.
It seems correct to you means "compile on some implementations"
Clearly you need to participate in implementation-specific groups to
share your implementation specific expertise, because here, it's not
correct.
Sep 30 '08 #6

P: n/a
On Sep 30, 3:54*pm, Keith Thompson <ks***@mib.orgwrote:
s0****@gmail.com writes:
On Sep 30, 2:46*pm, Keith Thompson <ks***@mib.orgwrote:
ar******@gmail.com writes:
If I have a piece of code something like this
void main(void)
{
* *char * p1="abcdefghijklmn";
* * .............................................
}
The correct declaration for main is "int main(void)".
But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:
<quote>
5.1.2.2.1 Program startup
[snip]
or equivalent;9) or in some other implementation-defined manner.
<end quote>
Thus, the prototype shown by the OP is also correct.

That depends on what you mean by "correct". *And no, I'm not playing
word games; it really does depend on what you mean by "correct".
I meant correct in the sense that it's valid according to the
standard.
An implementation is allowed, but not required, to support "void
main(void)". *(In fact, this is covered by the general permission to
support extensions; the "or in some other implementation-defined
manner" wording in 5.1.2.2.1 is redundant.)
But this would be the kind of extension that a compiler wouldn't be
able to accept in strictly conforming mode, isn't it? By being
explicitly mentioned in the standard, a compiler can now accept it in
so-called conforming mode.
So if the OP's particular implementation, for whatever reason,
supports "void main(void)" -- which means that it must *document* it,
not just accidentally fail to reject it -- then "void main(void)" is
arguably correct *for that implementation*. *But it's not portable; it
can be rejected, or can cause undefined behavior, on any
implementation that doesn't choose to support it.
Of course, "in an implementation-defined manner" means it will be
different across implementations. Personally I prefer to define it to
return int, and to omit the return statement. But I think it isn't
very accurate to say that "void main(void)" is "incorrect", only
because it will be rejected by some implementations.
For example, the
status code returned to the environment when the program terminates is
normally the int value returned from main(), or passed to exit(). If
main() doesn't return an int value, what status code does the
environment see? The standard certainly doesn't say; the
implementation may or may not document it.
Common sense says: 0 (or, more generally, the value that indicates
"normal" program termination, in case there's some obscure OS where 0
isn't such a value).

Sebastian

Oct 1 '08 #7

P: n/a
s0****@gmail.com writes:
On Sep 30, 3:54*pm, Keith Thompson <ks***@mib.orgwrote:
>s0****@gmail.com writes:
On Sep 30, 2:46*pm, Keith Thompson <ks***@mib.orgwrote:
ar******@gmail.com writes:
If I have a piece of code something like this
void main(void)
{
* *char * p1="abcdefghijklmn";
* * .............................................
}
>The correct declaration for main is "int main(void)".
But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:
<quote>
5.1.2.2.1 Program startup
[snip]
or equivalent;9) or in some other implementation-defined manner.
<end quote>
Thus, the prototype shown by the OP is also correct.

That depends on what you mean by "correct". *And no, I'm not playing
word games; it really does depend on what you mean by "correct".

I meant correct in the sense that it's valid according to the
standard.
Substituting "valid" for "correct" doesn't make it any clearer.

It's correct, valid, or whatever you want to call it only with respect
to a specific implementation, and only if that implementation
explicitly supports it.
>An implementation is allowed, but not required, to support "void
main(void)". *(In fact, this is covered by the general permission to
support extensions; the "or in some other implementation-defined
manner" wording in 5.1.2.2.1 is redundant.)

But this would be the kind of extension that a compiler wouldn't be
able to accept in strictly conforming mode, isn't it? By being
explicitly mentioned in the standard, a compiler can now accept it in
so-called conforming mode.
No. The requirement in 5.1.2.2.1 is not a constraint, which means
that violating it invokes undefined behavior; no diagnostic is
required. Since no strictly conforming program can use
"void main(void)", and no diagnostic is required for it, anything an
implementation does with it is within the bounds of the standard.

BTW, "strictly conforming" applies to programs, not to implementations
or modes. An implementation is conforming or it isn't.
>So if the OP's particular implementation, for whatever reason,
supports "void main(void)" -- which means that it must *document* it,
not just accidentally fail to reject it -- then "void main(void)" is
arguably correct *for that implementation*. *But it's not portable; it
can be rejected, or can cause undefined behavior, on any
implementation that doesn't choose to support it.

Of course, "in an implementation-defined manner" means it will be
different across implementations. Personally I prefer to define it to
return int, and to omit the return statement. But I think it isn't
very accurate to say that "void main(void)" is "incorrect", only
because it will be rejected by some implementations.
I certainly wouldn't call it "correct".
>For example, the
status code returned to the environment when the program terminates is
normally the int value returned from main(), or passed to exit(). If
main() doesn't return an int value, what status code does the
environment see? The standard certainly doesn't say; the
implementation may or may not document it.

Common sense says: 0 (or, more generally, the value that indicates
"normal" program termination, in case there's some obscure OS where 0
isn't such a value).
Common sense doesn't necessarily apply. I've used a compiler that
does the equivalent of "exit(1)" if you fall off the end of main()
without executing a return statement. This was perfectly valid
behavior according to the C90 standard (it wasn't a C99 compiler).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 1 '08 #8

P: n/a
On Oct 1, 12:12*am, Keith Thompson <ks***@mib.orgwrote:
s0****@gmail.com writes:
On Sep 30, 3:54*pm, Keith Thompson <ks***@mib.orgwrote:
s0****@gmail.com writes:
On Sep 30, 2:46*pm, Keith Thompson <ks***@mib.orgwrote:
ar******@gmail.com writes:
If I have a piece of code something like this
void main(void)
{
* *char * p1="abcdefghijklmn";
* * .............................................
}
The correct declaration for main is "int main(void)".
But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:
<quote>
5.1.2.2.1 Program startup
[snip]
or equivalent;9) or in some other implementation-defined manner.
<end quote>
Thus, the prototype shown by the OP is also correct.
That depends on what you mean by "correct". *And no, I'm not playing
word games; it really does depend on what you mean by "correct".
I meant correct in the sense that it's valid according to the
standard.

Substituting "valid" for "correct" doesn't make it any clearer.

It's correct, valid, or whatever you want to call it only with respect
to a specific implementation, and only if that implementation
explicitly supports it.
Yes, but, again, I was talking in regard to the standard, not to any
particular implementation.
An implementation is allowed, but not required, to support "void
main(void)". *(In fact, this is covered by the general permission to
support extensions; the "or in some other implementation-defined
manner" wording in 5.1.2.2.1 is redundant.)
But this would be the kind of extension that a compiler wouldn't be
able to accept in strictly conforming mode, isn't it? By being
explicitly mentioned in the standard, a compiler can now accept it in
so-called conforming mode.

No. *The requirement in 5.1.2.2.1 is not a constraint, which means
that violating it invokes undefined behavior; no diagnostic is
required. *Since no strictly conforming program can use
"void main(void)", and no diagnostic is required for it, anything an
implementation does with it is within the bounds of the standard.
What!? I'm not following. The quote I made from the standard mentions
three prototype forms for main: "int main(void)", "int main(int, char
**)" and "some other implementation-defined manner". Now, "void
main(void)" would fall under the third category; am I wrong? What do
you mean by saying that a strictly conforming program can't use "void
main(void)"?
BTW, "strictly conforming" applies to programs, not to implementations
or modes. *An implementation is conforming or it isn't.
So if the OP's particular implementation, for whatever reason,
supports "void main(void)" -- which means that it must *document* it,
not just accidentally fail to reject it -- then "void main(void)" is
arguably correct *for that implementation*. *But it's not portable; it
can be rejected, or can cause undefined behavior, on any
implementation that doesn't choose to support it.
Of course, "in an implementation-defined manner" means it will be
different across implementations. Personally I prefer to define it to
return int, and to omit the return statement. But I think it isn't
very accurate to say that "void main(void)" is "incorrect", only
because it will be rejected by some implementations.

I certainly wouldn't call it "correct".
If the standard says it is, why not?

Sebastian

Oct 1 '08 #9

P: n/a
s0****@gmail.com said:

<snip>
The quote I made from the standard mentions
three prototype forms for main: "int main(void)", "int main(int, char
**)" and "some other implementation-defined manner". Now, "void
main(void)" would fall under the third category; am I wrong? What do
you mean by saying that a strictly conforming program can't use "void
main(void)"?
Firstly, the Standard does not require any implementation to provide
support for *any* entry point other than int main(void), int main(int,
char **), and exact equivalents. (The rules for freestanding
implementations are even looser, but let's not go there just now.) There
is certainly no requirement to provide support for void main(void).

Therefore, even if a particular implementation defines a meaning for void
main(void), the behaviour of such a program on some *other* (arbitrary)
implementation is undefined.

Secondly, a strictly conforming program is one that "shall use only those
features of the language and library specified in this International
Standard.2) It shall not produce output dependent on any unspecified,
undefined, or implementation-defined behavior, and shall not exceed any
minimum implementation limit."

Since void main(void) is not specified by the Standard, and also since it
can't be demonstrated that the very use of void main(void) does not
produce output dependent on any unspecified, undefined, or
implementation-defined behaviour, it cannot be used in a strictly
conforming program.
Of course, "in an implementation-defined manner" means it will be
different across implementations. Personally I prefer to define it to
return int, and to omit the return statement. But I think it isn't
very accurate to say that "void main(void)" is "incorrect", only
because it will be rejected by some implementations.

I certainly wouldn't call it "correct".

If the standard says it is, why not?
The Standard doesn't say it's correct. It says that implementations are
allowed to define a meaning for it. But implementations are allowed to
define a meaning for anything they like - they can even give meaning to
Ook! programs if they want. But that doesn't make Ook! programs "correct"
in C terms.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 1 '08 #10

P: n/a
On Oct 1, 1:05*am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:

<snip>
The quote I made from the standard mentions
three prototype forms for main: "int main(void)", "int main(int, char
**)" and "some other implementation-defined manner". Now, "void
main(void)" would fall under the third category; am I wrong? What do
you mean by saying that a strictly conforming program can't use "void
main(void)"?

Firstly, the Standard does not require any implementation to provide
support for *any* entry point other than int main(void), int main(int,
char **), and exact equivalents. (The rules for freestanding
implementations are even looser, but let's not go there just now.) There
is certainly no requirement to provide support for void main(void).

Therefore, even if a particular implementation defines a meaning for void
main(void), the behaviour of such a program on some *other* (arbitrary)
implementation is undefined.
So far, the bottom line remains the same: it *is* correct; it simply
isn't guaranteed to work on every compiler.
Secondly, a strictly conforming program is one that "shall use only those
features of the language and library specified in this International
Standard.2) It shall not produce output dependent on any unspecified,
undefined, or implementation-defined behavior, and shall not exceed any
minimum implementation limit."

Since void main(void) is not specified by the Standard, and also since it
can't be demonstrated that the very use of void main(void) does not
produce output dependent on any unspecified, undefined, or
implementation-defined behaviour, it cannot be used in a strictly
conforming program.
Now that's a shocker. Does that mean that, say, bit-fields in
structures can't be used in a strictly conforming program? (Whether
bit-fields are stored from right to left or from left to right is
implementation-defined.) In fact, does that mean that variables of
type int, long, or any type other than char, can't be used in a
strictly conforming program because their sizes are also
implementation-defined?
Of course, "in an implementation-defined manner" means it will be
different across implementations. Personally I prefer to define it to
return int, and to omit the return statement. But I think it isn't
very accurate to say that "void main(void)" is "incorrect", only
because it will be rejected by some implementations.
I certainly wouldn't call it "correct".
If the standard says it is, why not?

The Standard doesn't say it's correct. It says that implementations are
allowed to define a meaning for it. But implementations are allowed to
define a meaning for anything they like - they can even give meaning to
Ook! programs if they want. But that doesn't make Ook! programs "correct"
in C terms.
But they'd be providing Ook! support as an extension (which would be
quite an useful extension, btw!). Accepting void main(void) isn't an
extension.

Sebastian

Oct 1 '08 #11

P: n/a
On Oct 1, 12:04 am, aruna...@gmail.com wrote:
Hi all,

If I have a piece of code something like this

void main(void)
{
char * p1="abcdefghijklmn";
.............................................

}

For p1 and whatever it points to , where is the memory allocated. Is
it on heap or stack or
some other common global area. I am assuming it should be either on
stack or some global area. Unless
a user does a malloc storage space cannot be allocated on heap is my
assumption. Can someone
throw some light on how compilers do this.

What if the above piece of code is changed to something like

void main(void)
{
char *p1;
char a[20]="abcdefgh";

strcpy(p1,a);

}

Now where is the space allocated for p1 and whatever it points to
after strcpy.

Thanks in advance.

Regards,
Ar
in your first example
char *p1 will be allocated on stack not on heap but "abcdefghijklmn"
will be stored as global
now comming to your second example i am sorry to say your code is
wrong ....see

as you declare a pointer without initializing it so where is points
is dependent on your linker and OS it will generally point to 0 ( that
is a null pointer) ....
so you cannot copy bytes to it strcpy(p1, a) ; that is wrong

right way to do it is

char *p1 = NULL;
p1 = a;
then no need for strcpy();

even in this example the pointer will still be allocated on the stack
not on heap;
Oct 1 '08 #12

P: n/a
On 1 okt, 09:27, s0s...@gmail.com wrote:
On Oct 1, 1:05*am, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:
<snip>
The quote I made from the standard mentions
three prototype forms for main: "int main(void)", "int main(int, char
**)" and "some other implementation-defined manner". Now, "void
main(void)" would fall under the third category; am I wrong? What do
you mean by saying that a strictly conforming program can't use "void
main(void)"?
Firstly, the Standard does not require any implementation to provide
support for *any* entry point other than int main(void), int main(int,
char **), and exact equivalents. (The rules for freestanding
implementations are even looser, but let's not go there just now.) There
is certainly no requirement to provide support for void main(void).
Therefore, even if a particular implementation defines a meaning for void
main(void), the behaviour of such a program on some *other* (arbitrary)
implementation is undefined.

So far, the bottom line remains the same: it *is* correct; it simply
isn't guaranteed to work on every compiler.
No. The phrase "some other implementation-defined manner" means that
void main() is only correct if the implementation documents it as
being so.
If the implementation does not document void main() as a possible
entry point, then using void main() with that implementation results
in UB, which means that this use of void main() can not be correct.

So, you can"t say without qualification that void main() is correct.
You can at most say that it is correct for certain implementations.
>
Secondly, a strictly conforming program is one that "shall use only those
features of the language and library specified in this International
Standard.2) It shall not produce output dependent on any unspecified,
undefined, or implementation-defined behavior, and shall not exceed any
minimum implementation limit."
Since void main(void) is not specified by the Standard, and also since it
can't be demonstrated that the very use of void main(void) does not
produce output dependent on any unspecified, undefined, or
implementation-defined behaviour, it cannot be used in a strictly
conforming program.

Now that's a shocker. Does that mean that, say, bit-fields in
structures can't be used in a strictly conforming program? (Whether
bit-fields are stored from right to left or from left to right is
implementation-defined.) In fact, does that mean that variables of
type int, long, or any type other than char, can't be used in a
strictly conforming program because their sizes are also
implementation-defined?
No, because you can write programs that don't depend on the
implementation defined aspects of bitfields or the integer types.

For example, this is a strictly conforming program:
<cut>
#include <stdio.h>
struct bits {
int value:4;
};
int main(void)
{
struct bits result;
int lhs, rhs;

lhs = 4;
rhs = 3;
result.value = lhs + rhs;
printf("%d\n", result.value);
return 0;
}
<cut>

The program is strictly conforming, because the output does not depend
on the choices that an implementation may have made for the
unspecified or implementation-defined behaviours or values.
>
Sebastian
Bart v Ingen Schenau
Oct 1 '08 #13

P: n/a
Bart van Ingen Schenau said:
On 1 okt, 09:27, s0s...@gmail.com wrote:
>On Oct 1, 1:05 am, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:
<snip>
The quote I made from the standard mentions
three prototype forms for main: "int main(void)", "int main(int,
char **)" and "some other implementation-defined manner". Now, "void
main(void)" would fall under the third category; am I wrong? What do
you mean by saying that a strictly conforming program can't use
"void main(void)"?
Firstly, the Standard does not require any implementation to provide
support for *any* entry point other than int main(void), int main(int,
char **), and exact equivalents. (The rules for freestanding
implementations are even looser, but let's not go there just now.)
There is certainly no requirement to provide support for void
main(void).
Therefore, even if a particular implementation defines a meaning for
void main(void), the behaviour of such a program on some *other*
(arbitrary) implementation is undefined.

So far, the bottom line remains the same: it *is* correct; it simply
isn't guaranteed to work on every compiler.

No. The phrase "some other implementation-defined manner" means that
void main() is only correct if the implementation documents it as
being so.
If the implementation does not document void main() as a possible
entry point, then using void main() with that implementation results
in UB, which means that this use of void main() can not be correct.

So, you can"t say without qualification that void main() is correct.
You can at most say that it is correct for certain implementations.
>>
Secondly, a strictly conforming program is one that "shall use only
those features of the language and library specified in this
International Standard.2) It shall not produce output dependent on any
unspecified, undefined, or implementation-defined behavior, and shall
not exceed any minimum implementation limit."
Since void main(void) is not specified by the Standard, and also since
it can't be demonstrated that the very use of void main(void) does not
produce output dependent on any unspecified, undefined, or
implementation-defined behaviour, it cannot be used in a strictly
conforming program.

Now that's a shocker. Does that mean that, say, bit-fields in
structures can't be used in a strictly conforming program? (Whether
bit-fields are stored from right to left or from left to right is
implementation-defined.) In fact, does that mean that variables of
type int, long, or any type other than char, can't be used in a
strictly conforming program because their sizes are also
implementation-defined?

No, because you can write programs that don't depend on the
implementation defined aspects of bitfields or the integer types.

For example, this is a strictly conforming program:
<cut>
#include <stdio.h>
struct bits {
int value:4;
};
int main(void)
{
struct bits result;
int lhs, rhs;

lhs = 4;
rhs = 3;
result.value = lhs + rhs;
printf("%d\n", result.value);
return 0;
}
<cut>

The program is strictly conforming,
If you change the struct def to:

struct bits {
signed int value:4;
};

you don't have to worry about whether passing an unsigned int to printf as
a match for %d is an issue or not (and since I can never remember myself
whether it is, I find it easier to make things explicitly correct).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 1 '08 #14

P: n/a
On 1 Oct, 09:44, raashid bhatt <raashidbh...@gmail.comwrote:
On Oct 1, 12:04 am, aruna...@gmail.com wrote:
If I have a piece of code something like this
void main(void)
{
* *char * p1="abcdefghijklmn";
* * .............................................
}
For p1 and *whatever it points to , where is the memory allocated. Is
it on heap or stack or
some other common global area. I am assuming it should be either on
stack or some global area. Unless
a user does a malloc storage space cannot be allocated on heap is my
assumption.
since The Standard doesn't mention heaps there is no restriction on an
implementaion using the heap (or stack) for whatever it pleases. The
static variables area could be stack or heap. (on old Macs the heap
was on the stack).

Can someone
throw some light on how compilers do this.
they have to allocate a block of memory before program startup.
How they do this is the implementors business. It is common
to just grab a lump of memory for statis data.

What if the above piece of code is changed to something like
void main(void)
{
* * char *p1;
* * char a[20]="abcdefgh";
* * strcpy(p1,a);
}
Now where is the space allocated for p1 and whatever it points to
after strcpy.

in your first example
char *p1 will be allocated on stack not on heap but "abcdefghijklmn"
will be stored as global
now comming to your second example i am sorry to say your code is
wrong ....see

as you declare a pointer without initializing *it so where is points
is dependent on your linker and OS it will generally point to 0 ( that
is a null pointer) ....
if by "generally" you mean "usually" I don't think this is so.
In my experience it contains whatever "random" crap has been
left on the stack. Many OSs *don't* clear the memory
before dishing it out to processes.
so you cannot copy bytes to it strcpy(p1, a) ; that is wrong

right way to do *it is

char *p1 = NULL;
initialising it to NULL is not necessary
p1 = a;
then no need for strcpy();
yes, but that may not be what the user wanted. he might
want to modify what p points to.

even in this example the pointer will still be allocated on the stack
not on heap

--
Nick Keighley
Oct 1 '08 #15

P: n/a
s0****@gmail.com said:
On Oct 1, 8:20 pm, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:On Oct 1, 5:14 am, Richard Heathfield
<rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
On Oct 1, 1:05 am, Richard Heathfield <rj*@see.sig.invalidwrote:

<snip>
>Therefore, even if a particular implementation defines a meaning
for void main(void), the behaviour of such a program on some
*other* (arbitrary) implementation is undefined.
So far, the bottom line remains the same: it *is* correct; it
simply isn't guaranteed to work on every compiler.
>It seems that we have a terminology disagreement again. I don't see
it as being "correct". I know it fails on at least two
implementations that I use regularly.
But, speaking strictly in regard to the standard, we can say it is
correct, since it is explicitly mentioned there.

C&V, please. Where does the Standard explicitly say that void main(void)
is "correct"? Indeed, where does the Standard explicitly mention void
main(void) at all?

It is implied by "or in some other implementation-defined manner" in
5.1.2.2.1.
No, the Standard does not imply by that text that void main(void) is
"correct", any more than the Standard implies by the same text that struct
{ double d; struct tm t; } main(double *d, long(*f)(void *, double) is
correct. The Standard grants permission for implementations to define
their own entry point signatures (which they can do anyway because it's a
perfectly valid extension), but it does not require every implementation
to support every other implementation's entry point signatures. So if you
use an extension, you're on your own when it comes to portability.
Perhaps that's not as explicit as it would be if it clearly
stated something like "main shall be defined as void main(void)", but
at least it's more explicit than simply allowing it to be accepted as
an extension (or as a result of UB).
No, it's UB clear and simple, except on C99 implementations that support
it, on which it's implementation-defined.
Given that wording in 5.1.2.2.1, we can now think of it as "correct"
No, *you* can because *you* make up new meanings for words as you go along,
but people who know what they're talking about think of it as a crock.

<snip>
According to the horrifying truth I've just learned, this program
isn't conforming

Yes, it is. It isn't *strictly* conforming, but it is conforming.

And the only difference between that example and one that contains
void main(void) is that here we're providing a check so that we won't
overflow 'i'.
No, there's another difference, which is that in *this* program you got
main()'s signature right, so that isn't a cause of undefined behaviour.
There is no way to check if the compiler recognizes void
main(void),
Right, so don't rely on void main(void), use int main(void) instead.
but such is also the case for bit-fields ordering
Right, so don't rely on bit-fields ordering, but write your code in a way
that doesn't require that dependence instead. Getting the idea now?

and perhaps other features I can't think of right now.
In each case, if you can write the code without depending on such features,
you're onto a winner.
So do you agree now that void main(void) it *is* correct,
No, your constant repetition of this idiocy does not suddenly spring into
meaningful focus - it remains idiocy, no matter how many times you repeat
it.
and that
even though it can't be used in a "strictly conforming" program, it
can be used in a "conforming" one?
The category of "conforming program" is not a useful one, since it's so
broad. Fortran programs are conforming C programs as far as gcc is
concerned.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 2 '08 #16

P: n/a
s0****@gmail.com writes:
On Oct 1, 8:20*pm, Richard Heathfield <rj*@see.sig.invalidwrote:
[...]
>C&V, please. Where does the Standard explicitly say that void main(void) is
"correct"? Indeed, where does the Standard explicitly mention void
main(void) at all?

It is implied by "or in some other implementation-defined manner" in
5.1.2.2.1. Perhaps that's not as explicit as it would be if it clearly
stated something like "main shall be defined as void main(void)", but
at least it's more explicit than simply allowing it to be accepted as
an extension (or as a result of UB).
You are wrong.

A statement like "main shall be defined as void main(void)" (which
doesn't occur in the standard) has a completely different meaning than
the "or in some other implementation-defined manner" that actually
does occur in the standard. It's not just more or less explicit, it's
a *different statement*.
Given that wording in 5.1.2.2.1, we can now think of it as "correct"
and not necessarily as UB, even though it will yield correct results
in some implementations and UB in others.
By the same reasoning, we can now thing if it as UB and not
necessarily as "correct", even though it will invoke UB in some
implementations and be "correct" in others.

[...]
And the only difference between that example and one that contains
void main(void) is that here we're providing a check so that we won't
overflow 'i'.
Um, there's also the fact that one uses "void main(void)" and the
other doesn't.
There is no way to check if the compiler recognizes void
main(void), but such is also the case for bit-fields ordering and
perhaps other features I can't think of right now.
C99 4p8:

An implementation shall be accompanied by a document that defines
all implementation-defined and locale-specific characteristics and
all extensions.

So you can check whether a compiler recognizes void main(void) by
reading its documentation.
So do you agree now that void main(void) it *is* correct, and that
even though it can't be used in a "strictly conforming" program, it
can be used in a "conforming" one?
You're right that it can't be used in a strictly conforming program
and that it can be used in a conforming one. If you'll look at the
standard, you'll understand that the meaning of a "conforming program"
is almost uselessly broad. And no, I absolutely do not agree that
void main(void) is "correct".

What point are you really trying to make here, anyway? This entire
debate seems to be about the meaning of the word "correct", not about
the C language. Are you arguing just for the sake of arguing, or is
there some point to all this? Is there any real disagreement about
what the standard says, or are just playing word games?

You do understand, don't you, that some implementations allow
"void main(void)" and others don't, but that all hosted
implementations allow "int main(void)"? I don't think you've
explicitly advocated using "void main(void)" in real code; do you
think it should be used? If so, why? If not, why are you so
interested in attempting to prove that it's "correct"?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 2 '08 #17

P: n/a
vi******@gmail.com said:
On Oct 2, 12:39 pm, gaze...@shell.xmission.com (Kenny McCormack)
wrote:
<snip>
>If my implementation documents the behavior of void main(void),
then it is required to behave as documented. I believe even KT would
agree on this point.

False, it's not required to.
Even a clock that runs backwards is correct occasionally - and how often
this happens depends only on how wrong it was to start with and how fast
it spins.

Let's focus on C99, since the whole "it's implementation-defined" business
was introduced therein. (In C90, the accuracy of documentation not
pertaining to the requirements of the Standard is a QoI issue.)

In C99, then, implementations are free to provide alternative signatures
for main "in an implementation-defined manner". Now, the Standard imposes
requirements on implementations for implementation-defined behaviour:
"each implementation documents how the choice is made". If you are right,
then implementations are free to document their choices with arbitrary
disregard for accuracy. For example, an implementation might claim in its
docs that INT_MAX is 65535 whereas it is actually 32767. So the question
is whether such an implementation is conforming (assuming it conforms in
all other ways).

Since the Standard doesn't define the verb "document", we have no
alternative but to read that word with its ordinary English meaning
(unless, of course, the word is defined in one of the normative
references, which is something I have no way of checking).

In Chambers, the verb "document" is defined as follows: "1. to record
something, especially in written form. 2. to provide written evidence to
support or prove something - from Latin /documentum/ lesson or proof."

Taking sense 1 first - if INT_MAX is 32767 but the implementation's
paperwork says that it's 65535, then it hasn't recorded the value of
INT_MAX. It has *mis*-recorded it. Taking sense 2 - if INT_MAX is 32767
but the implementation's paperwork says that it's 65535, then it is not
supporting INT_MAX's value, but undermining it. It is not proving it, but
lying about it. If X is Y but the lie is told that X is not-Y, the lie
neither proves that X is not-Y nor that X is Y. It's just a lie.

So it is not reasonable to suppose that documentation that the
implementation is required to provide for implementation-defined behaviour
is allowed to be incorrect.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 2 '08 #18

P: n/a
On Oct 2, 1:23*am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
On Oct 1, 8:20 pm, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:On Oct 1, 5:14 am, Richard Heathfield
<rj*@see.sig.invalidwrote:
s0****@gmail.com said:
On Oct 1, 1:05 am, Richard Heathfield <rj*@see.sig.invalidwrote:
<snip>
Therefore, even if a particular implementation defines a meaning
for void main(void), the behaviour of such a program on some
*other* (arbitrary) implementation is undefined.
So far, the bottom line remains the same: it *is* correct; it
simply isn't guaranteed to work on every compiler.
It seems that we have a terminology disagreement again. I don't see
it as being "correct". I know it fails on at least two
implementations that I use regularly.
But, speaking strictly in regard to the standard, we can say it is
correct, since it is explicitly mentioned there.
C&V, please. Where does the Standard explicitly say that void main(void)
is "correct"? Indeed, where does the Standard explicitly mention void
main(void) at all?
It is implied by "or in some other implementation-defined manner" in
5.1.2.2.1.

No, the Standard does not imply by that text that void main(void) is
"correct", any more than the Standard implies by the same text that struct
{ double d; struct tm t; } main(double *d, long(*f)(void *, double) is
correct.
Neither does it imply that int main(void) is correct, because, as you
said before, the standard doesn't define "correct". But back to *our*
opinions: if you don't consider 'struct { double d; struct tm t; }
main(double *d, long (*f)(void *, double))' correct, why do you
consider the program where I assign 33000 to an int to be correct?
(You said that it looked fine to you.) The only difference between
that example and struct { double d; struct tm t; } main(double *d,
long (*f)(void *, double)) is that the example shown provides a check
so that it will never fail. But other than that, they're the same:
both rely on implementation-defined behavior, and are therefore non-
strictly-conforming.

<snip>
Given that wording in 5.1.2.2.1, we can now think of it as "correct"

No, *you* can because *you* make up new meanings for words as you go along,
but people who know what they're talking about think of it as a crock.
If defining a word that isn't defined by the standard to describe a C
feature is making up new meanings for words, then yes, I'm making up a
new meaning for "correct". But so are you, making up a new meaning for
"crock".

<snip>
There is no way to check if the compiler recognizes void
main(void),

Right, so don't rely on void main(void), use int main(void) instead.
I usually do, but the point is whether void main(void) is correct.
but such is also the case for bit-fields ordering

Right, so don't rely on bit-fields ordering, but write your code in a way
that doesn't require that dependence instead. Getting the idea now?
I do, too, but the point is whether a program that relies on bit-
fields ordering is correct. Here's an example:

// Assumes right to left bit-field ordering
//
struct IEEEFloat
{
unsigned int fraction : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
}

union FloatMix
{
float native;
struct IEEEFloat ieee;
}

#include <stdio.h>

int main(void)
{
// will print -2.0 if 'float' is stored according
// to the IEEE floating point standard
printf("%f\n", (union FloatMix) {.ieee = {.sign = 1, .exponent =
128, .fraction = 0}}.native);
}

Do you consider this program "correct"? If yes, why do you not
consider void main(void) correct?
and perhaps other features I can't think of right now.

In each case, if you can write the code without depending on such features,
you're onto a winner.
So do you agree now that void main(void) it *is* correct,

No, your constant repetition of this idiocy does not suddenly spring into
meaningful focus - it remains idiocy, no matter how many times you repeat
it.
You haven't shown any valid arguments about why it isn't correct.

Sebastian

Oct 2 '08 #19

P: n/a
On Oct 2, 1:54*am, Keith Thompson <ks***@mib.orgwrote:
s0****@gmail.com writes:
On Oct 1, 8:20*pm, Richard Heathfield <rj*@see.sig.invalidwrote:
[...]
C&V, please. Where does the Standard explicitly say that void main(void) is
"correct"? Indeed, where does the Standard explicitly mention void
main(void) at all?
It is implied by "or in some other implementation-defined manner" in
5.1.2.2.1. Perhaps that's not as explicit as it would be if it clearly
stated something like "main shall be defined as void main(void)", but
at least it's more explicit than simply allowing it to be accepted as
an extension (or as a result of UB).

You are wrong.

A statement like "main shall be defined as void main(void)" (which
doesn't occur in the standard) has a completely different meaning than
the "or in some other implementation-defined manner" that actually
does occur in the standard. *It's not just more or less explicit, it's
a *different statement*.
It's different in the sense that one is a mandate, the other is a
permission. But they're both referring to the same subject. Moreover,
in C99, it is an *explicit* permission.
Given that wording in 5.1.2.2.1, we can now think of it as "correct"
and not necessarily as UB, even though it will yield correct results
in some implementations and UB in others.

By the same reasoning, we can now thing if it as UB and not
necessarily as "correct", even though it will invoke UB in some
implementations and be "correct" in others.
In a sense, yes, but I know a lot of people that think of C99 as
"allowing void main(void)" and of C89 as "*not* allowing void
main(void)". Now, I know this is just common sense, and it doesn't
really apply in CLC Pedants Club(tm), but I think it's worth taking it
in into account.

<snip>
* * * * * * * There is no way to check if the compiler recognizes void
main(void), but such is also the case for bit-fields ordering and
perhaps other features I can't think of right now.

C99 4p8:

* * An implementation shall be accompanied by a document that defines
* * all implementation-defined and locale-specific characteristics and
* * all extensions.

So you can check whether a compiler recognizes void main(void) by
reading its documentation.
Yes, but I was referring to providing a check in the code, as I did
with the #if directive.
So do you agree now that void main(void) it *is* correct, and that
even though it can't be used in a "strictly conforming" program, it
can be used in a "conforming" one?

You're right that it can't be used in a strictly conforming program
and that it can be used in a conforming one. *If you'll look at the
standard, you'll understand that the meaning of a "conforming program"
is almost uselessly broad. *And no, I absolutely do not agree that
void main(void) is "correct".

What point are you really trying to make here, anyway? *This entire
debate seems to be about the meaning of the word "correct", not about
the C language. *Are you arguing just for the sake of arguing, or is
there some point to all this? *Is there any real disagreement about
what the standard says, or are just playing word games?
At this point it *is* pretty much about the meaning of the word
"correct". Is it word games? Well, in a post at the beginning of this
thread you yourself said "And no, I'm not playing word games; it
really does depend on what you mean by "correct"." :-)
You do understand, don't you, that some implementations allow
"void main(void)" and others don't, but that all hosted
implementations allow "int main(void)"? *I don't think you've
explicitly advocated using "void main(void)" in real code; do you
think it should be used? *If so, why? *If not, why are you so
interested in attempting to prove that it's "correct"?
I don't think void main(void) is better than int main(void), of
course, but, aside from the issue of portability, I don't think
there's any reason not to use it (provided that you're using a
compiler that supports it). And I'm puzzled about the fact that you
don't consider it to be correct, even in C99.

Sebastian

Oct 2 '08 #20

P: n/a
Richard Heathfield wrote:
s0****@gmail.com said:
>On Oct 2, 1:23 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>>s0****@gmail.com said:
On Oct 1, 8:20 pm, Richard Heathfield <rj*@see.sig.invalidwrote:
....
accepted standards". Now, in the very narrow context of a C99
implementation that documents void main(void) in its conformance
documentation - and, incidentally, I know of no such implementation - it
C99 implementations are pretty rare, and therefore don't provide a good
sample size. I've heard that many popular C90 compilers permit void
int(void); do none of them document the fact that they permit it?

I can, unfortunately, confirm that this is the case for the only
compiler whose documentation I could quickly locate. gcc allows void
main(void), but "info gcc" section 4 "C implementation-defined behavior"
fails to mention void main(void), even though it says "A conforming
implementation of ISO C is required to document its choice of behavior
in each of the areas that are designated "implementation defined". The
following lists all such areas, ...".
>both rely on implementation-defined behavior, and are therefore non-
strictly-conforming.

True enough, but so what? I am not arguing that only strictly-conforming
programs are correct. I am arguing that void main(void) is not correct,
except that it may be just about possible for a truly pedantic language
lawyer to argue that it could be correct on C99 implementations that
document it as an alternative signature for main - but it would still be
incorrect on the vast majority of implementations, and indeed on ALL the
implementations I've ever used, and I've used a bundle.
void main(void) is permitted by the version of gcc installed on my home
machine (4.1.2 20070626 (Red Hat 4.1.2-13). This is true even when
compiling in either -std=c89 or -std=c99, even with all of my other
favorite options ( -pedantic -Wall -Wpointer-arith -Wcast-align
-Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes) turned on. It
produces a warning message, but it also generates an executable that
works as intended.
Oct 2 '08 #21

P: n/a
In article <af**********************************@d31g2000hsg. googlegroups.coms0****@gmail.com writes:
On Oct 2, 1:54=A0am, Keith Thompson <ks***@mib.orgwrote:
....
By the same reasoning, we can now thing if it as UB and not
necessarily as "correct", even though it will invoke UB in some
implementations and be "correct" in others.

In a sense, yes, but I know a lot of people that think of C99 as
"allowing void main(void)" and of C89 as "*not* allowing void
main(void)". Now, I know this is just common sense, and it doesn't
really apply in CLC Pedants Club(tm), but I think it's worth taking it
in into account.
But remember that C99 also allows: "double main(double)"...
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Oct 2 '08 #22

P: n/a
On Oct 2, 3:05 pm, Richard Heathfield <r...@see.sig.invalidwrote:
vipps...@gmail.com said:
On Oct 2, 12:39 pm, gaze...@shell.xmission.com (Kenny McCormack)
wrote:

<snip>
If my implementation documents the behavior of void main(void),
then it is required to behave as documented. I believe even KT would
agree on this point.
False, it's not required to.

Even a clock that runs backwards is correct occasionally - and how often
this happens depends only on how wrong it was to start with and how fast
it spins.

Let's focus on C99, since the whole "it's implementation-defined" business
was introduced therein. (In C90, the accuracy of documentation not
pertaining to the requirements of the Standard is a QoI issue.)

In C99, then, implementations are free to provide alternative signatures
for main "in an implementation-defined manner". Now, the Standard imposes
requirements on implementations for implementation-defined behaviour:
"each implementation documents how the choice is made". If you are right,
then implementations are free to document their choices with arbitrary
disregard for accuracy. For example, an implementation might claim in its
docs that INT_MAX is 65535 whereas it is actually 32767. So the question
is whether such an implementation is conforming (assuming it conforms in
all other ways).

Since the Standard doesn't define the verb "document", we have no
alternative but to read that word with its ordinary English meaning
(unless, of course, the word is defined in one of the normative
references, which is something I have no way of checking).

In Chambers, the verb "document" is defined as follows: "1. to record
something, especially in written form. 2. to provide written evidence to
support or prove something - from Latin /documentum/ lesson or proof."

Taking sense 1 first - if INT_MAX is 32767 but the implementation's
paperwork says that it's 65535, then it hasn't recorded the value of
INT_MAX. It has *mis*-recorded it. Taking sense 2 - if INT_MAX is 32767
but the implementation's paperwork says that it's 65535, then it is not
supporting INT_MAX's value, but undermining it. It is not proving it, but
lying about it. If X is Y but the lie is told that X is not-Y, the lie
neither proves that X is not-Y nor that X is Y. It's just a lie.

So it is not reasonable to suppose that documentation that the
implementation is required to provide for implementation-defined behaviour
is allowed to be incorrect.
All that you say is fine and I'd agree if void main(void) was
"implementation defined behavior".
The reason I disagreed with Kenny and perhaps with you is that I think
void main(void) is UB in C99. (I don't know about C90, I don't have
that standard)

Here's why

5.1.2.2.1 Program startup p 1
The function called at program startup is named main. The implementation declares no
prototype for this function. It **shall** be defined with a returntype of int and with no
parameters:
Emphasis added by me.

Then, 4. Conformance p 1
In this International Standard, ''shall'' is to be interpreted as a requirement on an
implementation or on a program; conversely, ''shall not'' is to be interpreted as a
prohibition.
What this undoubtedly means is that the program is required to be
defined with a return type of int.
If not, it's UB. Do we agree on this interprentation?
If we do, can you claim the same you claimed about implementation
documentation for undefined behavior?
If you agree with me about void main(void), I think you can also agree
that the standard doesn't require an implementation to document UB. If
the implementation chooses so, it's outside of the scope of the C
stardard; whether the documentation lies or not is not C's concern.
Oct 2 '08 #23

P: n/a
vi******@gmail.com writes:
[...]
All that you say is fine and I'd agree if void main(void) was
"implementation defined behavior".
The reason I disagreed with Kenny and perhaps with you is that I think
void main(void) is UB in C99. (I don't know about C90, I don't have
that standard)

Here's why

5.1.2.2.1 Program startup p 1
>The function called at program startup is named main. The
implementation declares no prototype for this function. It
**shall** be defined with a return type of int and with no
parameters:
[I've fixed the "fi" ligature above.]
Emphasis added by me.

Then, 4. Conformance p 1
>In this International Standard, ''shall'' is to be interpreted as a
requirement on an implementation or on a program; conversely,
''shall not'' is to be interpreted as a prohibition.

What this undoubtedly means is that the program is required to be
defined with a return type of int.
If not, it's UB. Do we agree on this interprentation?
Um, no. I agree that C99 5.1.2.2.1p1 could be reasonably read that
way, and the wording should probably be cleaned up a bit, but I'm
almost certain that the *intent* is that main shall be defined:
as int main(void)
*OR*
as int main(int argc, char *argv[])
*OR*
in some other implementation-defined manner. I don't believe the
phrase "with a return type of int" was intended to cover the "some
other implementation-defined manner" case.

I note that the interpretation that it does calls for a somewhat
strained interpretation of the wording. The phrase "or in some other
implementation-defined manner" clearly (at least it's clear to me)
logically follows "It shall be defined". Compare my interpretation:
It shall be defined ... in some other implementation-defined
manner.
to yours:
It shall be defined with a return type of int ... in some other
implementation-defined manner.

As a matter of common sense (yes, I know that's a dangerous thing to
apply to the standard), I can't think of any good *reason* why an
implementation should be allowed to vary the parameters but not the
return type.

The problem with the current wording is that the phrase "with a return
type of int" appears only once, but is meant to apply to two of the
following three clauses. I think that's just a consequence of the
fact that C90 just has the first two clauses, and the third was tacked
on in C99.

But even if we accept your interpretation, that 5.1.2.2.1 doesn't
permit void main(void), 4p6 does (which is why I've long said that the
added permission in 5.1.2.2.1 is redundant):

A conforming implementation may have extensions (including
additional library functions), provided they do not alter the
behavior of any strictly conforming program.

and 4p8:

An implementation shall be accompanied by a document that defines
all implementation-defined and locale-specific characteristics and
all extensions.

Ignoring the added phrase in 5.1.2.2.1, "void main(void)" is a valid
extension. As such, an implementation that supports it is required to
document it. The documentation requirement is meaningless if an
implementation is allowed to lie in its own documentation.

In the absence of such documentation, the behavior of void main(void)
is undefined. And if an implementation does support void main(void),
it needn't behave in the obvious manner. A conforming implementation
could, as a documented extension, say that this program:
void main(void) { }
prints "main returns int, you fool!" on stderr.
If we do, can you claim the same you claimed about implementation
documentation for undefined behavior?
If you agree with me about void main(void), I think you can also agree
that the standard doesn't require an implementation to document UB. If
the implementation chooses so, it's outside of the scope of the C
stardard; whether the documentation lies or not is not C's concern.
If an implementation defines behavior that is not defined by the
standard in the document required by C99 4p8, then it must do so
accurately.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 2 '08 #24

P: n/a
s0****@gmail.com writes:
On Oct 2, 1:54*am, Keith Thompson <ks***@mib.orgwrote:
>s0****@gmail.com writes:
On Oct 1, 8:20*pm, Richard Heathfield <rj*@see.sig.invalidwrote:
[...]
>C&V, please. Where does the Standard explicitly say that void
main(void) is "correct"? Indeed, where does the Standard
explicitly mention void main(void) at all?
It is implied by "or in some other implementation-defined manner" in
5.1.2.2.1. Perhaps that's not as explicit as it would be if it clearly
stated something like "main shall be defined as void main(void)", but
at least it's more explicit than simply allowing it to be accepted as
an extension (or as a result of UB).

You are wrong.

A statement like "main shall be defined as void main(void)" (which
doesn't occur in the standard) has a completely different meaning than
the "or in some other implementation-defined manner" that actually
does occur in the standard. *It's not just more or less explicit, it's
a *different statement*.

It's different in the sense that one is a mandate, the other is a
permission. But they're both referring to the same subject. Moreover,
in C99, it is an *explicit* permission.
You seem to be implying that the difference between a mandate and a
permission is not very significant. I'm just going to give up on
trying to figure out what point you're trying to make here.

But C90 provides the same permission in section 4, where it permits
extensions (supporting "void main(void)" is a valid extension).
Given that wording in 5.1.2.2.1, we can now think of it as "correct"
and not necessarily as UB, even though it will yield correct results
in some implementations and UB in others.

By the same reasoning, we can now thing if it as UB and not
necessarily as "correct", even though it will invoke UB in some
implementations and be "correct" in others.

In a sense, yes, but I know a lot of people that think of C99 as
"allowing void main(void)" and of C89 as "*not* allowing void
main(void)". Now, I know this is just common sense, and it doesn't
really apply in CLC Pedants Club(tm), but I think it's worth taking it
in into account.
People who think that C99 allows "void main(void)" and C89 doesn't (if
there are any such people) are mistaken. Both versions of the
standard explicitly allow extensions that don't affect the behavior of
strictly conforming code.

[...]
>What point are you really trying to make here, anyway? *This entire
debate seems to be about the meaning of the word "correct", not about
the C language. *Are you arguing just for the sake of arguing, or is
there some point to all this? *Is there any real disagreement about
what the standard says, or are just playing word games?

At this point it *is* pretty much about the meaning of the word
"correct". Is it word games? Well, in a post at the beginning of this
thread you yourself said "And no, I'm not playing word games; it
really does depend on what you mean by "correct"." :-)
And your apparent meaning of "correct" is one that I find absurd.

I agree that "void main(void)" is correct for an implementation that
supports it. But suppose I'm using a conforming compiler that rejects
any program that declared "void main(void)". If I write a program
that declares "void main(void)" and submit it to that compiler, I'm
out of luck. And this is what you call "correct" -- not just for a
particular implementation, but without qualification.
>You do understand, don't you, that some implementations allow
"void main(void)" and others don't, but that all hosted
implementations allow "int main(void)"? *I don't think you've
explicitly advocated using "void main(void)" in real code; do you
think it should be used? *If so, why? *If not, why are you so
interested in attempting to prove that it's "correct"?

I don't think void main(void) is better than int main(void), of
course, but, aside from the issue of portability, I don't think
there's any reason not to use it (provided that you're using a
compiler that supports it). And I'm puzzled about the fact that you
don't consider it to be correct, even in C99.
I'm puzzled by your puzzlement. And I'm equally puzzled as to why you
would consider using "void main(void)" even with a compiler that
supports it. It gains you nothing over "int main(void)".

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 2 '08 #25

P: n/a
James Kuyper said:
Richard Heathfield wrote:
>s0****@gmail.com said:
>>On Oct 2, 1:23 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
On Oct 1, 8:20 pm, Richard Heathfield <rj*@see.sig.invalidwrote:
...
>accepted standards". Now, in the very narrow context of a C99
implementation that documents void main(void) in its conformance
documentation - and, incidentally, I know of no such implementation - it

C99 implementations are pretty rare, and therefore don't provide a good
sample size. I've heard that many popular C90 compilers permit void
int(void);
Presumably you mean void main(void) - I don't know of any compilers that
permit void int(void)!
do none of them document the fact that they permit it?
Not in their conformance docs, no. That is, none that I've ever used - and
I've used a few.
I can, unfortunately, confirm that this is the case for the only
compiler whose documentation I could quickly locate. gcc allows void
main(void), but "info gcc" section 4 "C implementation-defined behavior"
fails to mention void main(void),
Quite so.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 2 '08 #26

P: n/a
In article <ln************@nuthaus.mib.org>,
Keith Thompson <ks***@mib.orgwrote:
....
>But C90 provides the same permission in section 4, where it permits
extensions (supporting "void main(void)" is a valid extension).
Exactly.

....
>I'm puzzled by your puzzlement. And I'm equally puzzled as to why you
would consider using "void main(void)" even with a compiler that
supports it. It gains you nothing over "int main(void)".
My point (with the silly $700B example) was that it might.
My implementation (particularly if it is, an in my example, an embedded
[non-hosted] environment) might give extra functionality (as an
extension) if I write void main(void).

As you say, extensions are permitted, and, most importantly, the
standard says nothing about what void main(void)[*] can or can't do.
[*] Hereinafter, let's abbreviate this as vmv, since I predict we will
be discussing this for years to come.

Oct 2 '08 #27

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
(the standard only guarantees that 'int' can
represent up to 32767), but it will never fail. Is this program
"incorrect" according to the standard?

It depends which Standard we're talking about. It's incorrect under C89,
but correct under C99.
What's different in C99 that makes you say that?
--
Larry Jones

Why can't I ever build character in a Miami condo or a casino somewhere?
-- Calvin
Oct 2 '08 #28

P: n/a
la************@siemens.com said:
Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
(the standard only guarantees that 'int' can
represent up to 32767), but it will never fail. Is this program
"incorrect" according to the standard?

It depends which Standard we're talking about. It's incorrect under C89,
but correct under C99.

What's different in C99 that makes you say that?
C99 codifies // (and since we're on the subject, it also codifies falling
off the end of main).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 2 '08 #29

P: n/a
James Kuyper <ja*********@verizon.netwrote:
>
C99 implementations are pretty rare, and therefore don't provide a good
sample size. I've heard that many popular C90 compilers permit void
int(void); do none of them document the fact that they permit it?
As far as I know, almost all of the implementations that "permit" it
only do so accidentially, not as a deliberate extension. That is, they
don't do anything to specifically allow it, but they don't bother to
forbid it, either, which is a perfectly acceptable course of action for
undefined behavior. If the resulting (undefined) behavior is innocuous,
as it usually is, it *appears* that the implementation supports it when
it really doesn't. That's one of the reasons that the "or in some other
implementation-defined manner" wording was added to C99: to emphasize
that appearing to work is not sufficient, the implementation must also
document it or it's just an accident, not intentional support.
--
Larry Jones

I sure wish I could get my hands on some REAL dynamite. -- Calvin
Oct 2 '08 #30

P: n/a
On Oct 2, 8:54*am, "Dik T. Winter" <Di********@cwi.nlwrote:
In article <af**********************************@d31g2000hsg. googlegroups..coms0****@gmail.com writes:

*On Oct 2, 1:54=A0am, Keith Thompson <ks***@mib.orgwrote:
...
* By the same reasoning, we can now thing if it as UB and not
* necessarily as "correct", even though it will invoke UB in some
* implementations and be "correct" in others.
*>
*In a sense, yes, but I know a lot of people that think of C99 as
*"allowing void main(void)" and of C89 as "*not* allowing void
*main(void)". Now, I know this is just common sense, and it doesn't
*really apply in CLC Pedants Club(tm), but I think it's worth taking it
*in into account.

But remember that C99 also allows: "double main(double)"...
Exactly. It also allows void main(void) and struct { double d; struct
tm t; } main(double *d, long (*f)(void *, double)). That's the point.
And yet, Keith Thompson and Richard Heathfield insist it isn't
"correct", when it's even mentioned in the standard.

Sebastian

Oct 2 '08 #31

P: n/a
On Oct 2, 11:06*am, Keith Thompson <ks***@mib.orgwrote:
s0****@gmail.com writes:
On Oct 2, 1:54*am, Keith Thompson <ks***@mib.orgwrote:
s0****@gmail.com writes:
On Oct 1, 8:20*pm, Richard Heathfield <rj*@see.sig.invalidwrote:
[...]
C&V, please. Where does the Standard explicitly say that void
main(void) is "correct"? Indeed, where does the Standard
explicitly mention void main(void) at all?
It is implied by "or in some other implementation-defined manner" in
5.1.2.2.1. Perhaps that's not as explicit as it would be if it clearly
stated something like "main shall be defined as void main(void)", but
at least it's more explicit than simply allowing it to be accepted as
an extension (or as a result of UB).
You are wrong.
A statement like "main shall be defined as void main(void)" (which
doesn't occur in the standard) has a completely different meaning than
the "or in some other implementation-defined manner" that actually
does occur in the standard. *It's not just more or less explicit, it's
a *different statement*.
It's different in the sense that one is a mandate, the other is a
permission. But they're both referring to the same subject. Moreover,
in C99, it is an *explicit* permission.

You seem to be implying that the difference between a mandate and a
permission is not very significant. *I'm just going to give up on
trying to figure out what point you're trying to make here.

But C90 provides the same permission in section 4, where it permits
extensions (supporting "void main(void)" is a valid extension).
In C90, and in regard to implementations, vmv may or may not be an
extension (if it isn't, it's simply UB). In regard to the standard,
it's simply UB.

In C99, and in regard to implementations, it's similar as for C90:
whether it supports vmv or not is implementation-defined (and if it
isn't supported, it's simply UB). In regard to the *standard*,
however, vmv is allowed, and therefore (by the dictionary definition
of "correct") it's correct.

<snip>
What point are you really trying to make here, anyway? *This entire
debate seems to be about the meaning of the word "correct", not about
the C language. *Are you arguing just for the sake of arguing, or is
there some point to all this? *Is there any real disagreement about
what the standard says, or are just playing word games?
At this point it *is* pretty much about the meaning of the word
"correct". Is it word games? Well, in a post at the beginning of this
thread you yourself said "And no, I'm not playing word games; it
really does depend on what you mean by "correct"." :-)

And your apparent meaning of "correct" is one that I find absurd.

I agree that "void main(void)" is correct for an implementation that
supports it. *But suppose I'm using a conforming compiler that rejects
any program that declared "void main(void)". *If I write a program
that declares "void main(void)" and submit it to that compiler, I'm
out of luck. *And this is what you call "correct" -- not just for a
particular implementation, but without qualification.
I'm not qualifying it with any particular implementation, but I am
qualifying it with the standard (i.e., by its wording).
You do understand, don't you, that some implementations allow
"void main(void)" and others don't, but that all hosted
implementations allow "int main(void)"? *I don't think you've
explicitly advocated using "void main(void)" in real code; do you
think it should be used? *If so, why? *If not, why are you so
interested in attempting to prove that it's "correct"?
I don't think void main(void) is better than int main(void), of
course, but, aside from the issue of portability, I don't think
there's any reason not to use it (provided that you're using a
compiler that supports it). And I'm puzzled about the fact that you
don't consider it to be correct, even in C99.

I'm puzzled by your puzzlement. *And I'm equally puzzled as to why you
would consider using "void main(void)" even with a compiler that
supports it. *It gains you nothing over "int main(void)".
I don't usually use void main(void), but I do think it's still
correct.

Sebastian

Oct 3 '08 #32

P: n/a
Richard Heathfield wrote:
James Kuyper said:
....
>sample size. I've heard that many popular C90 compilers permit void
int(void);

Presumably you mean void main(void) - I don't know of any compilers that
permit void int(void)!
Aiiiy! I'm getting old; the frequency with which my typos survive
multiple proofreading passes is getting pretty depressing. You should
see what my first drafts look like!
Oct 3 '08 #33

P: n/a
s0****@gmail.com said:
On Oct 2, 8:54 am, "Dik T. Winter" <Di********@cwi.nlwrote:
<snip>
>But remember that C99 also allows: "double main(double)"...

Exactly. It also allows void main(void) and struct { double d; struct
tm t; } main(double *d, long (*f)(void *, double)). That's the point.
And yet, Keith Thompson and Richard Heathfield insist it isn't
"correct", when it's even mentioned in the standard.
Note that void main(void) is NOT mentioned in the Standard.

Note, too, that lots of incorrect things are mentioned in the Standard.

Note, further, that even if void main(void) is acceptable to one
implementation, that does not imply that it is acceptable to others.

Note, finally, that a program that a conforming implementation refuses to
translate[1] can hardly be considered to be "correct".

[1, for pedants only] Modulo the whole #error business.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 3 '08 #34

P: n/a
s0****@gmail.com said:
On Oct 2, 8:29 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
On Oct 2, 1:23 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
On Oct 1, 8:20 pm, Richard Heathfield <rj*@see.sig.invalidwrote:
>C&V, please. Where does the Standard explicitly say that void
main(void) is "correct"? Indeed, where does the Standard
explicitly mention void main(void) at all?
It is implied by "or in some other implementation-defined manner"
in 5.1.2.2.1.
>No, the Standard does not imply by that text that void main(void) is
"correct", any more than the Standard implies by the same text that
struct
{ double d; struct tm t; } main(double *d, long(*f)(void *, double)
{ is
correct.
Neither does it imply

Fine, so it appears you accept that you were wrong about the
"implication" of 5.1.2.2.1.

Well, it doesn't mention the word "correct" itself. But the way you
said that the standard didn't imply that /void/ main(void) is
"correct" made it sound as if it did imply that /int/ main(void) is
correct.
On the contrary, it explicitly and unambiguously lists int main(void) as
one of the forms that main shall take (and int main(char *argv[]) as the
other. No other forms of main are explicitly and unambiguously listed. The
Standard does, however, point out that the implementation shall accept
equivalent forms (e.g. typedef int foo; foo main(foo argc, char **argv)
would be okay).
[...] it's not much of a fair comparison, and that's why I provided the
other example who's output is dependent on the bit-fields ordering,
but you didn't answer whether you consider it to be correct.
You did? Oh. I don't always read your stuff all the way to the bottom,
because you include so much irrelevant junk that it gets wearisome. No
doubt there are people around with more patience than me.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 3 '08 #35

P: n/a
s0****@gmail.com wrote:
On Sep 30, 2:46=A0pm, Keith Thompson <ks***@mib.orgwrote:
ar******@gmail.com writes:
void main(void)
The correct declaration for main is "int main(void)".

But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:
Not true. Or at least, not reliably true, and therefore not true within
the meaning of the act, yer'onner.
<quote>
or equivalent;9) or in some other implementation-defined manner.

<end quote>

Thus, the prototype shown by the OP is also correct.
Only correct where _explicitly_ allowed. Not correct everywhere.
Therefore, not correct when used in a general context (which, evidence
to the contrary lacking, any c.l.c post must be assumed to be).

But this is not my main point. That's this:

Suppose the OP had not written void main(void), but

union return_tuple main(struct env, char* __cmd_line__, bool intactv)

and Keith had responded to that with the same correction he wrote above,
would you even have considered bothering to respond? My money's on "no".
The contingent of M$-and-Ganoo-lovers who defend void main() almost
always are willing to defend _only_ void main(), and not any other
implementation-defined, non-standard form of main().
So why this discrimination? It can't be that you seriously believe that
void main() is correct, and other non-standard main()s are not. That
would be too dumb even for a Ganoohead.

Richard
Oct 3 '08 #36

P: n/a
On Oct 3, 2:59*am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
<snip>
[...] it's not much of a fair comparison, and that's why I provided the
other example who's output is dependent on the bit-fields ordering,
but you didn't answer whether you consider it to be correct.

You did? Oh. I don't always read your stuff all the way to the bottom,
because you include so much irrelevant junk that it gets wearisome. No
doubt there are people around with more patience than me.
OK, this time I'm only including the code:

// Assumes right to left bit-field ordering
//
struct IEEEFloat
{
unsigned int fraction : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
};

union FloatMix
{
float native;
struct IEEEFloat ieee;
};

#include <stdio.h>

int main(void)
{
// will print -2.0 if 'float' is stored according
// to the IEEE floating point standard

printf("%f\n", (union FloatMix) {.ieee = {.sign = 1, .exponent =
128, .fraction = 0}}.native);
}

The code is not strictly conforming. But is it correct? If yes, why
isn't void main(void) correct?

Sebastian

Oct 3 '08 #37

P: n/a
On Oct 3, 5:46*am, rl*@hoekstra-uitgeverij.nl (Richard Bos) wrote:
s0****@gmail.com wrote:
On Sep 30, 2:46=A0pm, Keith Thompson <ks***@mib.orgwrote:
ar******@gmail.com writes:
void main(void)
The correct declaration for main is "int main(void)".
But it's not the /only/ correct one. There's also "int main(int, char
**)", or anything your implementation supports:

Not true. Or at least, not reliably true, and therefore not true within
the meaning of the act, yer'onner.
<quote>
or equivalent;9) or in some other implementation-defined manner.
<end quote>
Thus, the prototype shown by the OP is also correct.

Only correct where _explicitly_ allowed. Not correct everywhere.
Therefore, not correct when used in a general context (which, evidence
to the contrary lacking, any c.l.c post must be assumed to be).

But this is not my main point. That's this:

Suppose the OP had not written void main(void), but

* union return_tuple main(struct env, char* __cmd_line__, bool intactv)

and Keith had responded to that with the same correction he wrote above,
would you even have considered bothering to respond? My money's on "no".
The contingent of M$-and-Ganoo-lovers who defend void main() almost
always are willing to defend _only_ void main(), and not any other
implementation-defined, non-standard form of main().
So why this discrimination? It can't be that you seriously believe that
void main() is correct, and other non-standard main()s are not. That
would be too dumb even for a Ganoohead.
Well, unlike some people here, I do usually take common sense into
account, so I would certainly have wondered about the purpose of
main() returning a union. But I think I would've pointed it out
anyway, because I don't say that void main(void) is correct because
MSVC allows it, but because the C99 standard allows it.

Sebastian

Oct 3 '08 #38

P: n/a
s0****@gmail.com said:
On Oct 3, 2:59 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:

<snip>
[...] it's not much of a fair comparison, and that's why I provided
[the
other example who's output is dependent on the bit-fields ordering,
but you didn't answer whether you consider it to be correct.

You did? Oh. I don't always read your stuff all the way to the bottom,
because you include so much irrelevant junk that it gets wearisome. No
doubt there are people around with more patience than me.

OK, this time I'm only including the code:

// Assumes right to left bit-field ordering
//
struct IEEEFloat
{
unsigned int fraction : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
};

union FloatMix
{
float native;
struct IEEEFloat ieee;
};

#include <stdio.h>

int main(void)
{
// will print -2.0 if 'float' is stored according
// to the IEEE floating point standard

printf("%f\n", (union FloatMix) {.ieee = {.sign = 1, .exponent =
128, .fraction = 0}}.native);
}

The code is not strictly conforming. But is it correct?
I have no opinion on that code. People who are more familiar with C99
features than I am might wish to comment.
If yes, why isn't void main(void) correct?
Whether the above code is correct or not, void main(void) is not correct
except in the following circumstances:

(a) as the entry point in a program written specifically for translation by
a freestanding implementation, where the implementation's conformance
documentation documents it as such;
(b) as the entry point in a program written specifically for translation by
a C99 implementation, where the implementation's conformance documentation
documents it as such.

In all other situations - i.e. the vast and overwhelming majority of
situations - it is incorrect.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 3 '08 #39

P: n/a
s0****@gmail.com writes:
On Oct 3, 2:59*am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:

<snip>
[...] it's not much of a fair comparison, and that's why I provided the
other example who's output is dependent on the bit-fields ordering,
but you didn't answer whether you consider it to be correct.

You did? Oh. I don't always read your stuff all the way to the bottom,
because you include so much irrelevant junk that it gets wearisome. No
doubt there are people around with more patience than me.

OK, this time I'm only including the code:

// Assumes right to left bit-field ordering
//
struct IEEEFloat
{
unsigned int fraction : 23;
unsigned int exponent : 8;
unsigned int sign : 1;
};

union FloatMix
{
float native;
struct IEEEFloat ieee;
};

#include <stdio.h>

int main(void)
{
// will print -2.0 if 'float' is stored according
// to the IEEE floating point standard

printf("%f\n", (union FloatMix) {.ieee = {.sign = 1, .exponent =
128, .fraction = 0}}.native);
}

The code is not strictly conforming. But is it correct? If yes, why
isn't void main(void) correct?
I've stayed out of this so far because I have no idea what you mean by
correct. I think it is best simply to avoid the term altogether.

Outside of the very narrow notion of a strictly conforming program[1]
(which has almost no practical value) C programs are simply more or
less portable. The code above may suite some purpose so the loss of
portability may be worth it.

The trouble with void main is that there is no up side. People use it
because they've seen it and don't know that int main is universal.
far better to help the world learn that there is portable alternative
that has no down side than to try to make a case for the alternative.

[1] I think this was forced on the committee by ISO rules -- they had
to define such a thing no matter how limited it turned out to be.

--
Ben.
Oct 3 '08 #40

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
[...]
Whether the above code is correct or not, void main(void) is not correct
except in the following circumstances:

(a) as the entry point in a program written specifically for translation by
a freestanding implementation, where the implementation's conformance
documentation documents it as such;
(b) as the entry point in a program written specifically for translation by
a C99 implementation, where the implementation's conformance documentation
documents it as such.
(c) as an ordinary function in a program written specifically for
translation by a freestanding implementation, where the
implementation's conformance documentation documents that the entry
point is not called "main";

(d) as the entry point in a program written specifically for
translation by a C99 implementation, where the implementation's
conformance documentation documents it *as an extension*.
In all other situations - i.e. the vast and overwhelming majority of
situations - it is incorrect.
Agreed.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 3 '08 #41

P: n/a
On Oct 3, 1:00*pm, Keith Thompson <ks***@mib.orgwrote:
Richard Heathfield <rj*@see.sig.invalidwrites:

[...]
Whether the above code is correct or not, void main(void) is not correct
except in the following circumstances:
(a) as the entry point in a program written specifically for translation by
a freestanding implementation, where the implementation's conformance
documentation documents it as such;
(b) as the entry point in a program written specifically for translation by
a C99 implementation, where the implementation's conformance documentation
documents it as such.

(c) as an ordinary function in a program written specifically for
translation by a freestanding implementation, where the
implementation's conformance documentation documents that the entry
point is not called "main";

(d) as the entry point in a program written specifically for
translation by a C99 implementation, where the implementation's
conformance documentation documents it *as an extension*.
(e) as the entry point in *any* program, provided that we're talking
strictly in regard to the standard, and not to any particular
implementation.

Sebastian

Oct 3 '08 #42

P: n/a
Keith Thompson <ks***@mib.orgwrites:
Richard Heathfield <rj*@see.sig.invalidwrites:
[...]
>Whether the above code is correct or not, void main(void) is not correct
except in the following circumstances:

(a) as the entry point in a program written specifically for translation by
a freestanding implementation, where the implementation's conformance
documentation documents it as such;
(b) as the entry point in a program written specifically for translation by
a C99 implementation, where the implementation's conformance documentation
documents it as such.

(c) as an ordinary function in a program written specifically for
translation by a freestanding implementation, where the
implementation's conformance documentation documents that the entry
point is not called "main";

(d) as the entry point in a program written specifically for
translation by a C99 implementation, where the implementation's
conformance documentation documents it *as an extension*.
Whoops. In (d) I meant "by a *C90" implementation (since C90 doesn't
have the "or in some other implementation-defined manner" clause but
does allow extensions). Though I suppose it could apply to C99 as
well; a C99 implementation can support "void main(void)" as an
extension without citing 5.1.2.2.1.
>In all other situations - i.e. the vast and overwhelming majority of
situations - it is incorrect.

Agreed.
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 3 '08 #43

P: n/a
s0****@gmail.com writes:
On Oct 3, 1:00*pm, Keith Thompson <ks***@mib.orgwrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:

[...]
Whether the above code is correct or not, void main(void) is not correct
except in the following circumstances:
(a) as the entry point in a program written specifically for translation by
a freestanding implementation, where the implementation's conformance
documentation documents it as such;
(b) as the entry point in a program written specifically for translation by
a C99 implementation, where the implementation's conformance documentation
documents it as such.

(c) as an ordinary function in a program written specifically for
translation by a freestanding implementation, where the
implementation's conformance documentation documents that the entry
point is not called "main";

(d) as the entry point in a program written specifically for
translation by a C99 implementation, where the implementation's
conformance documentation documents it *as an extension*.

(e) as the entry point in *any* program, provided that we're talking
strictly in regard to the standard, and not to any particular
implementation.
That is not a useful definition of correct. You are suggesting that
if any one implementation gives meaning to some construct (provided
that that meaning is a permitted extension) then it is correct by your
usage.

But that begs the question: does there even have to be an
implementation? It anything permitted by the standard part of a
correct program? If so (and I can't see why you'd say otherwise) then
almost anything is correct C. So

haskell {
fib = 1 : 1 : map (uncurry (+)) (zip fib (tail fib))
}

is correct C?

--
Ben.
Oct 3 '08 #44

P: n/a
s0****@gmail.com writes:
[...]
>Richard Heathfield <rj*@see.sig.invalidwrites:
[...]
Whether the above code is correct or not, void main(void) is not
correct except in the following circumstances:
[...]
(e) as the entry point in *any* program, provided that we're talking
strictly in regard to the standard, and not to any particular
implementation.
You have it exactly backwards. "void main(void)" is correct *only*
for a particular implementation that supports it.

Talking "strictly in regard to the standard", the standard allows an
implementation to *reject* a program that uses "void main(void)" -- or
to accept it and then behave in any nonsensical manner it chooses.
Apparently this is "correct" by your definition.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 4 '08 #45

P: n/a
s0****@gmail.com said:

<snip>
(e) as the entry point in *any* program, provided that we're talking
strictly in regard to the standard, and not to any particular
implementation.
Ah, I see the problem. You are confusing "conforming program" with "correct
program". A "conforming program" is one that is acceptable to a conforming
implementation. ("Strictly conforming programs" are something very
different indeed.)

I can certainly agree that void main(void), just like 10 IF X 0 THEN
GOSUB 5000, can be part of a conforming program. That doesn't mean it's
correct C.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Oct 4 '08 #46

P: n/a
On Oct 3, 2:29*pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:

<snip>
Outside of the very narrow notion of a strictly conforming program[1]
(which has almost no practical value)
<snip>
[1] I think this was forced on the committee by ISO rules -- they had
to define such a thing no matter how limited it turned out to be.
curious. I thought the original C89 standard which first defined
Stricttly
Conforming was done by ANSI. Or did ANSI have to corform with ISO
rules?

--
Nick Keighley
Oct 4 '08 #47

P: n/a
Nick Keighley <ni******************@hotmail.comwrites:
On Oct 3, 2:29*pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:

<snip>
>Outside of the very narrow notion of a strictly conforming program[1]
(which has almost no practical value)

<snip>
>[1] I think this was forced on the committee by ISO rules -- they had
to define such a thing no matter how limited it turned out to be.

curious. I thought the original C89 standard which first defined
Stricttly
Conforming was done by ANSI. Or did ANSI have to corform with ISO
rules?
Good point. I can't answer that. It could be the story is entirely
made up (by me or the person I though I heard it from!).

--
Ben.
Oct 4 '08 #48

P: n/a
On Oct 4, 2:49*am, s0s...@gmail.com wrote:
Well, unlike some people here, I do usually take common sense into
account, so I would certainly have wondered about the purpose of
main() returning a union. But I think I would've pointed it out
anyway, because I don't say that void main(void) is correct because
MSVC allows it, but because the C99 standard allows it.
Well, the C99 standard allows "Ook!" as a
program too (by your definition of "allows").

Is is "common sense" to you that "Ook!" is a
correct C program? It isn't to me!

Oct 4 '08 #49

P: n/a
On Oct 1, 10:35*am, jameskuy...@verizon.net wrote:
String literals are treated differently when they initialize char*
pointers than they are when they initialize char arrays. In the first
case, static memory is allocated for the contents of the string
literal, and the pointer is initialized with a value that points to
the first character of the array. It is not safe to attempt to write
to that array.

In the second case, the contents of the string literal are used to
directly initialize the declared array; no separate storage is
allocated.
Are you sure? My understanding is that the
string literal is still allocated, regardless
of what it's subsequently used for.

(Of course there is no way of telling because
of the as-if rule, it's just a language lawyer
question..)

Oct 4 '08 #50

50 Replies

This discussion thread is closed

Replies have been disabled for this discussion.