Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Params -> local vars?

Reply
Thread Tools

Params -> local vars?

 
 
Tim Rentsch
Guest
Posts: n/a
 
      09-07-2012
Jon Howson <(E-Mail Removed)> writes:

> Hello
>
> I was reading thru some (yellowing!) mimeographed introductory notes on C
> and I found code like the below.
>
> main(argc,argv)
> int argc;
> char *argv[];
> {
> char *malloc();
> char *strcpy();
> int puts();
> void free();
>
> char *s;
> if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
> strcpy(s,"Hello, ");
> strcpy(s+7,argv[1]);
> puts(s);
> free(s);
> }else{
> puts("Program failed, unknown error");
> }
> }
>
> I'm trying to work out what's happening. At the start of the function, I
> guess the parameters are being converted into local variables, maybe a
> way to get pass-by-value in C? [snip]


Just a few clarifications/additions to points made in other responses.

1. This style of parameter declaration (dating from more than 30
years ago, before C was standardized) is labelled 'obsolescent'
by the Standard. That means it's accepted now but don't count
on it being so in future revisions of the Standard. (On the other
hand it has been obsolescent for more than 20 years now.)

2. The newer (ie, current) style of parameter declarations is called
"prototypes", as for example

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

3. The prototype style of parameter declaration allows (and requires)
any call after the prototype declaration to have the types of its
arguments checked against the parameter types given in the prototype.
In contrast, the old style of parameter declaration does not do
such type checking (and the Standard says specifically that such
type checking will not be done).

4. The argument values are passed the same way in both cases,
except that, when old-style parameter declarations are used,
the parameter types are adjusted in some cases to reflect the
lack of knowledge about the types used. For example, a parameter
declared as 'char' will be passed as 'int' (or 'unsigned int' in
some implementations).

5. Except for the change of types mentioned in (4), how parameters
are used in function bodies is the same for both old-style and
the prototype form of parameter declaration.

6. Most people advise using the prototype declaration style when
writing any new code. I myself follow that advice in most cases
(and refrain now from trying to explain any of the exceptions).

7. For existing code using the older-style (aka "K&R style")
declarations, the most obvious benefit of changing it over to the
prototype form is better type checking. There are however two
gotcha's worth noting. One, the higher level of type checking
could produce compilation errors even though the code in question
works fine. (Of course it's also possible the code doesn't work
fine, and the type checking showed a problem.) Two, because of
the different rules for how parameter types work, it's possible
for a change that looks innocuous at face value to turn working
code into non-working code (and probably also the reverse, but I
think that's even less likely). So those changes are not ones
that should be made completely mindlessly and automatically.

8. (I'm skipping the question about the local function declarations
for malloc(), etc, because I don't have anything to add about
that here.)
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      09-08-2012
Tim Rentsch <(E-Mail Removed)> writes:
[...]
> 3. The prototype style of parameter declaration allows (and requires)
> any call after the prototype declaration to have the types of its
> arguments checked against the parameter types given in the prototype.
> In contrast, the old style of parameter declaration does not do
> such type checking (and the Standard says specifically that such
> type checking will not be done).

[...]

Checking is not *required*, but an implementation is free to perform it
anyway.

For example:

void func(arg)
int arg;
{
/* ... */
}

...

func("foo");

The call has undefined behavior. No diagnostic is required (and I
don't think I've seen a compiler warn about this), but (a) compilers
are free to warn about anything they like, and (b) given undefined
behavior that's detectable at compile time, a compiler is free to
treat it as a fatal error.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      09-08-2012
Keith Thompson <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
> [...]
>> 3. The prototype style of parameter declaration allows (and requires)
>> any call after the prototype declaration to have the types of its
>> arguments checked against the parameter types given in the prototype.
>> In contrast, the old style of parameter declaration does not do
>> such type checking (and the Standard says specifically that such
>> type checking will not be done).

> [...]
>
> Checking is not *required*, but an implementation is free to perform it
> anyway. [snip example]


Talking about function calls, 6.5.2.2 p 8 says "the number and
types of arguments are not compared with those of the parameters
in a function definition that does not include a function
prototype declarator."

You're right that implementations are free to issue any
diagnostics they want. At the same time, what is in those
diagnostics cannot depend on the results of comparisons
that implementations are prohibited from making.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      09-08-2012
Tim Rentsch <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:
>> Tim Rentsch <(E-Mail Removed)> writes:
>> [...]
>>> 3. The prototype style of parameter declaration allows (and requires)
>>> any call after the prototype declaration to have the types of its
>>> arguments checked against the parameter types given in the prototype.
>>> In contrast, the old style of parameter declaration does not do
>>> such type checking (and the Standard says specifically that such
>>> type checking will not be done).

>> [...]
>>
>> Checking is not *required*, but an implementation is free to perform it
>> anyway. [snip example]

>
> Talking about function calls, 6.5.2.2 p 8 says "the number and
> types of arguments are not compared with those of the parameters
> in a function definition that does not include a function
> prototype declarator."


The full paragraph is:

No other conversions are performed implicitly; in particular,
the number and types of arguments are not compared with those
of the parameters in a function definition that does not include
a function prototype declarator.

> You're right that implementations are free to issue any
> diagnostics they want. At the same time, what is in those
> diagnostics cannot depend on the results of comparisons
> that implementations are prohibited from making.


My suspicion is that the intent was not to forbid making those
comparisons, just that any argument conversions should not depend
on such comparisons. It certainly does *say* that the comparisons
are not performed, but it's in the context of implicit conversions.

It doesn't make much sense to forbid a compiler to perform
comparisons don't necessarily have any effect. And as long as
old-style function definitions are in the language, it would be nice
if some compilers could warn about calls with mismatched arguments.

Off to comp.std.c.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Richard Damon
Guest
Posts: n/a
 
      09-08-2012
On 9/8/12 8:09 AM, Tim Rentsch wrote:
> Keith Thompson <(E-Mail Removed)> writes:
>
>> Tim Rentsch <(E-Mail Removed)> writes:
>> [...]
>>> 3. The prototype style of parameter declaration allows (and requires)
>>> any call after the prototype declaration to have the types of its
>>> arguments checked against the parameter types given in the prototype.
>>> In contrast, the old style of parameter declaration does not do
>>> such type checking (and the Standard says specifically that such
>>> type checking will not be done).

>> [...]
>>
>> Checking is not *required*, but an implementation is free to perform it
>> anyway. [snip example]

>
> Talking about function calls, 6.5.2.2 p 8 says "the number and
> types of arguments are not compared with those of the parameters
> in a function definition that does not include a function
> prototype declarator."
>
> You're right that implementations are free to issue any
> diagnostics they want. At the same time, what is in those
> diagnostics cannot depend on the results of comparisons
> that implementations are prohibited from making.
>


The implementation is not prohibited from making any comparisons that it
might want to make, and can say what ever it wants to say, as long as it
prints at least some sort of diagnostic message for a program that
violates a constraint.

It is free to emit a message for anything it wants, even for things that
are "valid code". It is still conforming to issue warnings for things
like unneeded parenthesis or missing unneeded parenthesis that some
coding style might suggest be included due to people often getting
things wrong.

The resulting program output from the implementation (only required if
the program violates no constraints) must produce the standard defined
behavior (for as long as the standard defines the behavior, possibly
with some implementation defined behavior when that is mandated by the
standard). Since calling a non-prototyped function with the wrong
parameter types is not a constraint violation, the compiler can not use
this as grounds to not produce a resulting program (although when/if the
call occurs it creates undefined behavior), but it is free to make what
ever warnings it wants.




 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      12-17-2012
Richard Damon <(E-Mail Removed)> writes:

> On 9/8/12 8:09 AM, Tim Rentsch wrote:
>> Keith Thompson <(E-Mail Removed)> writes:
>>
>>> Tim Rentsch <(E-Mail Removed)> writes:
>>> [...]
>>>> 3. The prototype style of parameter declaration allows (and requires)
>>>> any call after the prototype declaration to have the types of its
>>>> arguments checked against the parameter types given in the prototype.
>>>> In contrast, the old style of parameter declaration does not do
>>>> such type checking (and the Standard says specifically that such
>>>> type checking will not be done).
>>> [...]
>>>
>>> Checking is not *required*, but an implementation is free to perform it
>>> anyway. [snip example]

>>
>> Talking about function calls, 6.5.2.2 p 8 says "the number and
>> types of arguments are not compared with those of the parameters
>> in a function definition that does not include a function
>> prototype declarator."
>>
>> You're right that implementations are free to issue any
>> diagnostics they want. At the same time, what is in those
>> diagnostics cannot depend on the results of comparisons
>> that implementations are prohibited from making.

>
> The implementation is not prohibited from making any comparisons that it
> might want to make, and can say what ever it wants to say, as long as it
> prints at least some sort of diagnostic message for a program that
> violates a constraint. [snip elaboration]


If you're arguing that the wording of 6.5.2.2 p 8 allows more
than one interpretation, and that interpretation might not
disallow such checking, I agree that aspect is debatable.

If you're arguing that implementations are always free to issue
diagnostics, regardless of how the restrictions in 6.5.2.2 p 8 are
worded, I can't agree with that -- the license to issue diagnostics
does not trump the obligation to meet all other requirements in the
Standard, whatever they are, for all conforming implementations.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
.NET 2.0: Sending email on local domain to local exchange 2K server Jim in Arizona ASP .Net 8 01-24-2006 05:37 PM
Access local port or Running local exe file =?Utf-8?B?WVNVVA==?= ASP .Net 0 01-14-2006 12:41 AM
params v.s. @params in rails? Barry Ruby 9 09-15-2005 03:12 AM
Browser link to local file works when local, not work when servedfrom http lurker HTML 1 04-05-2005 05:10 AM
Can't use 'local' to find sql server instances on local machine karim ASP .Net 1 06-26-2003 09:17 PM



Advertisments