Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > is this declaration correct

Reply
Thread Tools

is this declaration correct

 
 
Eric Sosman
Guest
Posts: n/a
 
      07-22-2012
On 7/18/2012 4:39 PM, Raj Pashwar wrote:
> Rather than
> include <stdio.h> can I use int printf(const char *,...) correct at all
> places if I only use printf in my program..


When I was very young and just getting started with my
first programming language -- FORTRAN II, it was -- I came
up with a way to avoid the IF statement by using a "computed
GO TO" instead. Wasn't I just the cleverest little precious
goody-smarts you can imagine?

Yes, you can write free-hand printf() declarations. It's
not as much of a challenge as doing without IF, but if it makes
you feel like a clever little precious goody-smarts, go ahead.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d
 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      07-22-2012
Keith Thompson <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
>>>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>>>> Rather than
>>>>>> include <stdio.h> can I use int printf(const char *,...) correct at all
>>>>>> places if I only use printf in my program..
>>>>>
>>>>> You *can*, but there's no good reason to do so.
>>> [30 lines deleted]
>>>>> Just write "#include <stdio.h>" and be done with it.
>>>>
>>>> Thanks for the informations. Conclusion seems to be that my definition
>>>> will work fine though may be sub-optimal.
>>>
>>> That may be the conclusion that you drew, but it's certainly not
>>> what I intended. More precisely, your statement is correct, but
>>> not particularly useful.
>>>
>>> In particular, if your implementation defines printf with the
>>> "restrict" keyword, and you declare it without "restrict", it may
>>> make your program's behavior undefined (I'd have to dig into the
>>> wording in the standard to be sure). [snip]

>>
>> Now that it is being pointed out, I'm confident you will
>> find the relevant passage or passages and post a correction.

>
> Not exactly. [snip long and careful response]


I apologize. My response should have been more direct.

The declarations

int printf( const int *, ... );
int printf( const int * restrict, ... );

are interchangeable, for the same reason that the declarations

int foo( int );
int foo( const int );

are interchangeable. I had thought a hint would be enough to lead
you fairly immediately to the definition of type compatibility for
function types (which is 6.7.6.3 p15 in N1570). The last sentence
of that paragraph (unchanged since N1256) says

(In the determination of type compatibility and of a
composite type, each parameter declared with function or
array type is taken as having the adjusted type and each
parameter declared with qualified type is taken as having
the unqualified version of its declared type.)

Note the last part of the sentence, following 'and each'. I was
pretty sure you knew all this but had just forgotten, which is
why I chose a short, elliptical response. Again, my apologies.

> So by declaring printf yourself (without the "restrict" rather
> than including <stdio.h>, you are at worst invoking undefined
> behavior, and at best depending on a potentially ambiguous line
> of reasoning -- and imposing that line of reasoning on anyone who
> reads or maintains the code.


I was meaning to argue that the behavior is in fact well-defined,
and unambiguously so. I think you'll agree that the sentence
quoted above shows that.

> It *might* save some time by avoiding
> having to process <stdio.h> (surely a tiny fraction of the time
> we've spent debating it). And it doesn't extend to functions that
> depend on the declaration of FILE.
>
> Or you can just write "#include <stdio.h>", which is *much*
> easier, guaranteed to be correct, and consistent with what 99%
> of C programmers use and expect.


I pretty much agree with your style points, and said something
along similar lines in my direct response to OP. However, I think
the two questions (ie, is the declaration correct, and is it
stylistically advisable) should not be intertwined, but rather
addressed separately. Also, when one goal of the OP was to
limit the scope of where 'printf' is available, I think it is
worth observing that this goal can be met only by a stand-alone
declaration, without including <stdio.h>, even if we might
also want to offer a style opinion as to the advisability of
having such a goal in the first place. Really, all I'm advocating
is, give the technical answers first, and stylistic advice second
and separately.
 
Reply With Quote
 
 
 
 
Tim Rentsch
Guest
Posts: n/a
 
      07-22-2012
Phil Carmody <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Phil Carmody <(E-Mail Removed)> writes:
>>
>> > Raj Pashwar <(E-Mail Removed)> writes:

>> [snip]
>> >> also allows Principal of Data Hiding (localize
>> >> declaration to a block and prevent name leakage elsewhere).
>> >
>> > That's not data hiding. That name is not permitted to exist anywhere
>> > except as the standard library defines it, [snip[

>>
>> That's not exactly right. Defining a library function (such
>> as printf()) yourself is undefined behavior, but the Standard
>> doesn't actually disallow it.

>
> You're playing with the semantics of "disallow". I'm pretty sure
> the standard doesn't disallow:
>
> -- 8< -------
> #!/usr/bin/perl
> $_="krJhruaesrltre c a cnP,ohet";$_.=$1,print$2while s/(..)(.)//;
> -- 8< -------
>
> In fact, it looks like 5.1.1.3 specifically *allows* it, as it
> defines part of the implementation's behaviour when fed such
> a translation unit. (Either with or without the snip markers!)
>
> However, such definitions of "allow", "disallow", "permit", etc.
> are not useful except when playing games of language-lawyery,
> in which case, we'd all up our pedantry.


I disagree, both generally for didactic reasons, and here
specifically for more practical reasons.

The general reasons are, basically, there are in fact some things
that the Standard disallows, and knowing that is a useful
distinction in certain cases. Glossing over the difference will
lead to trouble down the road; there are lots of things that are
just undefined behavior (as opposed to syntax errors or
constraint violations, which are truly disallowed), but in
practice some undefined behaviors are "more undefined" than
others. The grayness of this spectrum of various undefined
behaviors has a nice, sharp edge at one end, the point at which
certain program constructs are actually /not allowed/. It's
useful to keep that edge sharp in explanations, and conversely it
is confusing to blur it by labelling some undefined behaviors as
"disallowed". They are not disallowed, and it's a disservice to
the readers here to say they are.

The more specific reason is, not only is defining library
functions allowed (UB, but still allowed), this technique is
actually used on occasion in implementations that support it.
Calling it disallowed leads to an impossible world model,
contradicted by actual working (and conforming) programs
that make use of it.

Certainly I am not above making a pedantic comment. In this
case, however, it is not pedantry, but rather a conern for
the understanding of those who are new to these concepts
and find them confusing enough even without any blurring,
that prompts me to point out the distinctions here.
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      07-22-2012
Phil Carmody <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Raj Pashwar <(E-Mail Removed)> writes:
>>
>> > Rather than
>> > include <stdio.h> can I use int printf(const char *,...) correct at all
>> > places if I only use printf in my program..

> ...
>> 4. Ignore the scare tactics of the naysayers implying that this
>> declaration of printf is somehow less reliable than just
>> including <stdio.h>. The declaration you give is absolutely
>> guaranteed to work. The idea that it will have some effect
>> on performance is conceivable but not likely, and even less
>> likely to be relevant.

>
> 4b. Ignore the scare tactics of those who tell you, once you've
> included stdlib.h, to write:
>
> type_t *p = malloc(sizeof(*p));
>
> rather than:
>
> type_t *p = (type_t *)malloc(sizeof(type_t));
>
> The former is absolutely guaranteed to work.
>
> Good advice, no?


The scare tactics I was referring to (ie, for declaring printf)
were allusions to things _that cannot happen_. Casting the
result of malloc() can cause real problems, and, AFAIAA, actually
does cause problems in some implementations (if stdlib.h has not
been included). There's a difference between, on the one hand,
accurately reporting a problem that's actually been observed (in
the case of malloc()), and on the other hand alluding to possible
problems that have never been observed, and even in some cases
cannot be observed because the underlying assumptions are wrong.
It's only the second of these that fall under the label of "scare
tactics", as I was intending the term.

> I'm tempted to say a cost-risk-benefit analysis
> would favour my advice even more than yours, given what I've
> actually seen go wrong over the decades. E.g. gcc's format mismatch
> warnings trap many portability gotchas as well as grosser bugs -
> cost zero, risk zero, benefit palpable.


Are you assuming that arguments to printf() are diagnosed (with
warning messages) only if <stdio.h> is included? The gcc that I
have diagnoses printf() arguments whether or not the header is
included (given suitable compiler option switches, obviously).

I'm not opposed to offering style advice. However, I think it
should be presented as such, and always should reflect _actual_
potential concerns, not _imagined_ concerns that either have no
basis in actual experience or, even worse, misrepresent how the
language is defined and what it is required to do. I don't think
the misrepresentations in this thread were intentional, but I do
think there were misrepresentations, and they deserve to be
called out as such. So I don't think it's wrong to label them
as "scare tactics".
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-22-2012
Tim Rentsch <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:
>> Tim Rentsch <(E-Mail Removed)> writes:
>>> Keith Thompson <(E-Mail Removed)> writes:
>>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>>> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
>>>>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>>>>> Rather than
>>>>>>> include <stdio.h> can I use int printf(const char *,...) correct at all
>>>>>>> places if I only use printf in my program..
>>>>>>
>>>>>> You *can*, but there's no good reason to do so.
>>>> [30 lines deleted]
>>>>>> Just write "#include <stdio.h>" and be done with it.
>>>>>
>>>>> Thanks for the informations. Conclusion seems to be that my definition
>>>>> will work fine though may be sub-optimal.
>>>>
>>>> That may be the conclusion that you drew, but it's certainly not
>>>> what I intended. More precisely, your statement is correct, but
>>>> not particularly useful.
>>>>
>>>> In particular, if your implementation defines printf with the
>>>> "restrict" keyword, and you declare it without "restrict", it may
>>>> make your program's behavior undefined (I'd have to dig into the
>>>> wording in the standard to be sure). [snip]
>>>
>>> Now that it is being pointed out, I'm confident you will
>>> find the relevant passage or passages and post a correction.

>>
>> Not exactly. [snip long and careful response]

>
> I apologize. My response should have been more direct.
>
> The declarations
>
> int printf( const int *, ... );
> int printf( const int * restrict, ... );


(You mean const char *, not const int *, yes?)

> are interchangeable, for the same reason that the declarations
>
> int foo( int );
> int foo( const int );
>
> are interchangeable. I had thought a hint would be enough to lead
> you fairly immediately to the definition of type compatibility for
> function types (which is 6.7.6.3 p15 in N1570). The last sentence
> of that paragraph (unchanged since N1256) says
>
> (In the determination of type compatibility and of a
> composite type, each parameter declared with function or
> array type is taken as having the adjusted type and each
> parameter declared with qualified type is taken as having
> the unqualified version of its declared type.)


Thanks, I should have found that myself.

But look at 6.7.6p2:

Each declarator declares one identifier, and asserts that
when an operand of the same form as the declarator appears
in an expression, it designates a function or object with the
scope, storage duration, and type indicated by the declaration
specifiers.

The types of

int printf( const char *, ... );
int printf( const char * restrict, ... );

are *compatible*, but they aren't *the same*, which is what 6.7.6p2
requires.

6.7.6p2 says that the declaration "asserts" that they're the same
type. It doesn't directly say what happens if that assertion fails;
I presume the behavior is undefined.

Is there a clearer statement about the requirement for declarations to
match definitions? For example, if I declare

int printf(const char*); /* note: non-variadic */

and then call printf("Hello, world\n"), the behavior is undefined; is
this explicitly stated somewhere?

[...]

>> Or you can just write "#include <stdio.h>", which is *much*
>> easier, guaranteed to be correct, and consistent with what 99%
>> of C programmers use and expect.

>
> I pretty much agree with your style points, and said something
> along similar lines in my direct response to OP. However, I think
> the two questions (ie, is the declaration correct, and is it
> stylistically advisable) should not be intertwined, but rather
> addressed separately. Also, when one goal of the OP was to
> limit the scope of where 'printf' is available, I think it is
> worth observing that this goal can be met only by a stand-alone
> declaration, without including <stdio.h>, even if we might
> also want to offer a style opinion as to the advisability of
> having such a goal in the first place. Really, all I'm advocating
> is, give the technical answers first, and stylistic advice second
> and separately.


Ok, but I think the stylistic advice is important in this case. My
impression of your response to the OP was that didn't sufficiently
emphasize that part.

--
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
 
Tim Rentsch
Guest
Posts: n/a
 
      07-22-2012
Keith Thompson <(E-Mail Removed)> writes:

> Tim Rentsch <(E-Mail Removed)> writes:
>> Keith Thompson <(E-Mail Removed)> writes:
>>> Tim Rentsch <(E-Mail Removed)> writes:
>>>> Keith Thompson <(E-Mail Removed)> writes:
>>>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>>>> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
>>>>>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>>>>>> Rather than
>>>>>>>> include <stdio.h> can I use int printf(const char *,...) correct at all
>>>>>>>> places if I only use printf in my program..
>>>>>>>
>>>>>>> You *can*, but there's no good reason to do so.
>>>>> [30 lines deleted]
>>>>>>> Just write "#include <stdio.h>" and be done with it.
>>>>>>
>>>>>> Thanks for the informations. Conclusion seems to be that my definition
>>>>>> will work fine though may be sub-optimal.
>>>>>
>>>>> That may be the conclusion that you drew, but it's certainly not
>>>>> what I intended. More precisely, your statement is correct, but
>>>>> not particularly useful.
>>>>>
>>>>> In particular, if your implementation defines printf with the
>>>>> "restrict" keyword, and you declare it without "restrict", it may
>>>>> make your program's behavior undefined (I'd have to dig into the
>>>>> wording in the standard to be sure). [snip]
>>>>
>>>> Now that it is being pointed out, I'm confident you will
>>>> find the relevant passage or passages and post a correction.
>>>
>>> Not exactly. [snip long and careful response]

>>
>> I apologize. My response should have been more direct.
>>
>> The declarations
>>
>> int printf( const int *, ... );
>> int printf( const int * restrict, ... );

>
> (You mean const char *, not const int *, yes?)


Yes I did, thank you (although it doesn't change the point about
using 'restrict').

>> are interchangeable, for the same reason that the declarations
>>
>> int foo( int );
>> int foo( const int );
>>
>> are interchangeable. I had thought a hint would be enough to lead
>> you fairly immediately to the definition of type compatibility for
>> function types (which is 6.7.6.3 p15 in N1570). The last sentence
>> of that paragraph (unchanged since N1256) says
>>
>> (In the determination of type compatibility and of a
>> composite type, each parameter declared with function or
>> array type is taken as having the adjusted type and each
>> parameter declared with qualified type is taken as having
>> the unqualified version of its declared type.)

>
> Thanks, I should have found that myself.
>
> But look at 6.7.6p2:
>
> Each declarator declares one identifier, and asserts that
> when an operand of the same form as the declarator appears
> in an expression, it designates a function or object with the
> scope, storage duration, and type indicated by the declaration
> specifiers.
>
> The types of
>
> int printf( const char *, ... );
> int printf( const char * restrict, ... );
>
> are *compatible*, but they aren't *the same*, which is what 6.7.6p2
> requires.


The key question here is what type is "indicated". The answer to
that is specified in 6.2.7 p4:

For an identifier with internal or external linkage declared
in a scope in which a prior declaration of that identifier
is visible, if the prior declaration specifies internal or
external linkage, the type of the identifier at the later
declaration becomes the composite type.

Note that the last sentence of 6.7.6.3 p15 also applies to the
formation of the composite type in this case.

> 6.7.6p2 says that the declaration "asserts" that they're the same
> type. It doesn't directly say what happens if that assertion fails;
> I presume the behavior is undefined.


The type being asserted simply changes as the program text
proceeds. I don't think there is anything very mysterious
about this. If we have code like

int a[];
...
a[0] = 0;
...
int a[10];
a[0] = 1;

the type of 'a' is incomplete at the first assignment, and
complete at the second assignment. There is nothing that
requires these two types to be the same; each declarator
asserts what it asserts until (possibly) changed by a
subsequent declarator.

> Is there a clearer statement about the requirement for declarations to
> match definitions? For example, if I declare
>
> int printf(const char*); /* note: non-variadic */
>
> and then call printf("Hello, world\n"), the behavior is undefined; is
> this explicitly stated somewhere?


The call is UB because of 6.5.2.3 p9.

The declaration is UB because of 6.2.7 p2.

Because printf() is called, 6.9 p5 requires that printf() be
defined (or else UB).

Of course, there is the question of how printf() is defined,
hosted implementation, yada yada yada. But you know all
that.

>>> Or you can just write "#include <stdio.h>", which is *much*
>>> easier, guaranteed to be correct, and consistent with what 99%
>>> of C programmers use and expect.

>>
>> I pretty much agree with your style points, and said something
>> along similar lines in my direct response to OP. However, I think
>> the two questions (ie, is the declaration correct, and is it
>> stylistically advisable) should not be intertwined, but rather
>> addressed separately. Also, when one goal of the OP was to
>> limit the scope of where 'printf' is available, I think it is
>> worth observing that this goal can be met only by a stand-alone
>> declaration, without including <stdio.h>, even if we might
>> also want to offer a style opinion as to the advisability of
>> having such a goal in the first place. Really, all I'm advocating
>> is, give the technical answers first, and stylistic advice second
>> and separately.

>
> Ok, but I think the stylistic advice is important in this case. My
> impression of your response to the OP was that didn't sufficiently
> emphasize that part.


I am perfectly okay with different people having different opinions
on points of style. Generally I try to avoid style battles whenever
possible. What bothered me, I think, was so many people focusing on
the style concerns at the expense of what the OP really was trying to
ask about. I feel like his questions, and what intentions motivated
those questions, got lost in the noise of giving style advice. As
long as that point is addressed, clearly and distinctly, I'm okay
with however much emphasis people want to give on the style issues;
in fact how much style concerns are emphasized is itself a kind of
style issue. On this particular issue I think our goals are actually
not that far apart; where we may differ is in what approach will
most help achieve those goals. You might be interested to know that
partly I was inspired by an aphorism from another posting of yours
(on a different topic, not that that matters), which was "when in
doubt, learn the rules, thereby removing the doubt" (or something
along those lines anyway). I think that's an excellent aphorism,
and was pleased that OP had (unconsciously) adopted it.

I hope you've enjoyed my comments even if we haven't yet
reached 100% agreement.
 
Reply With Quote
 
Phil Carmody
Guest
Posts: n/a
 
      07-22-2012
Tim Rentsch <(E-Mail Removed)> writes:

> Phil Carmody <(E-Mail Removed)> writes:
>
> > Tim Rentsch <(E-Mail Removed)> writes:
> >> Raj Pashwar <(E-Mail Removed)> writes:
> >>
> >> > Rather than
> >> > include <stdio.h> can I use int printf(const char *,...) correct at all
> >> > places if I only use printf in my program..

> > ...
> >> 4. Ignore the scare tactics of the naysayers implying that this
> >> declaration of printf is somehow less reliable than just
> >> including <stdio.h>. The declaration you give is absolutely
> >> guaranteed to work. The idea that it will have some effect
> >> on performance is conceivable but not likely, and even less
> >> likely to be relevant.

> >
> > 4b. Ignore the scare tactics of those who tell you, once you've
> > included stdlib.h, to write:
> >
> > type_t *p = malloc(sizeof(*p));
> >
> > rather than:
> >
> > type_t *p = (type_t *)malloc(sizeof(type_t));
> >
> > The former is absolutely guaranteed to work.
> >
> > Good advice, no?

>
> The scare tactics I was referring to (ie, for declaring printf)
> were allusions to things _that cannot happen_. Casting the
> result of malloc() can cause real problems, and, AFAIAA, actually
> does cause problems in some implementations (if stdlib.h has not
> been included). There's a difference between, on the one hand,
> accurately reporting a problem that's actually been observed (in
> the case of malloc()), and on the other hand alluding to possible
> problems that have never been observed, and even in some cases
> cannot be observed because the underlying assumptions are wrong.
> It's only the second of these that fall under the label of "scare
> tactics", as I was intending the term.
>
> > I'm tempted to say a cost-risk-benefit analysis
> > would favour my advice even more than yours, given what I've
> > actually seen go wrong over the decades. E.g. gcc's format mismatch
> > warnings trap many portability gotchas as well as grosser bugs -
> > cost zero, risk zero, benefit palpable.

>
> Are you assuming that arguments to printf() are diagnosed (with
> warning messages) only if <stdio.h> is included? The gcc that I
> have diagnoses printf() arguments whether or not the header is
> included (given suitable compiler option switches, obviously).


That surprises me, but it appears to be true. I had assumed that as
the .h files were decorated, the compiler knew of these properties
only because of the decoration. Clearly I had ASSumed incorrectly. As
I say, I find that surprising, and I don't like my compiler surprising
me, even when it's trying to be helpful. Whether it's also true about
all the insights that the #include gives, I don't know.

> I'm not opposed to offering style advice. However, I think it
> should be presented as such, and always should reflect _actual_
> potential concerns, not _imagined_ concerns that either have no
> basis in actual experience or, even worse, misrepresent how the
> language is defined and what it is required to do. I don't think
> the misrepresentations in this thread were intentional, but I do
> think there were misrepresentations, and they deserve to be
> called out as such. So I don't think it's wrong to label them
> as "scare tactics".


OK, accepted.

Phil
--
> I'd argue that there is much evidence for the existence of a God.

Pics or it didn't happen.
-- Tom (/. uid 822)
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-22-2012
Eric Sosman <(E-Mail Removed)> writes:

> On 7/18/2012 4:39 PM, Raj Pashwar wrote:
>> Rather than
>> include <stdio.h> can I use int printf(const char *,...) correct at all
>> places if I only use printf in my program..

>
> When I was very young and just getting started with my
> first programming language -- FORTRAN II, it was -- I came
> up with a way to avoid the IF statement by using a "computed
> GO TO" instead. Wasn't I just the cleverest little precious
> goody-smarts you can imagine?
>
> Yes, you can write free-hand printf() declarations. It's
> not as much of a challenge as doing without IF, but if it makes
> you feel like a clever little precious goody-smarts, go ahead.


Oh, please! I don't get any sense that the OP is revelling in having
"discovered" something smart.

There are lots motivations for posting a question like this, including
sounds pedagogic ones. It's true that the OP has not posted back to say
"OK, I'll never do that" but I think there's a good reason for that:
this very question (right down to the quote from Stroustrup) has been
posted here many times -- at least in 2001 and again in 2010. It's
almost certainly homework, and the OP's summary ("It's legal but not
optimal") is probably the answer he's going to submit.

--
Ben.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-22-2012
Tim Rentsch <(E-Mail Removed)> writes:

> Ben Bacarisse <(E-Mail Removed)> writes:
>
>> Raj Pashwar <(E-Mail Removed)> writes:
>>
>>> On Wed, 18 Jul 2012 14:09:01 -0700, Keith Thompson wrote:
>>>
>>>> Raj Pashwar <(E-Mail Removed)> writes:
>>>>> Rather than
>>>>> include <stdio.h> can I use int printf(const char *,...) correct at all
>>>>> places if I only use printf in my program..
>>>>
>>>> You *can*, but there's no good reason to do so.

>> <snip details>
>>>> Just write "#include <stdio.h>" and be done with it.
>>>
>>> Thanks for the informations. Conclusion seems to be that my definition
>>> will work fine though may be sub-optimal.
>>>
>>> I see a few reasons to declare the function without the header, ie speeds
>>> up compilation, also allows Principal of Data Hiding (localize
>>> declaration to a block and prevent name leakage elsewhere).

>>
>> The second point is rather odd because it conflicts with another: the
>> principle of least surprise.

>
> Not that this matters really, but historically the Law of Least
> Astonishment (as it used to be called) arose in connection with
> the design of programming languages rather than the design of
> programs (assuming my memory on the subject is correct, which it
> may not be). So the allusion to it here caused (for me at least)
> the more general principle to be violated.


I'm not a fan of rules and laws (who's in charge of them anyway). It
was just as way to say "try to avoid oddities" -- little more than a
slightly specific form of the vague advice to write clear code.

>> C programmer expect printf to be, well, the global printf they
>> know, so localising its declaration will surprise your readers.

>
> Will it? If I saw a local declaration of printf(), I think I
> would assume the writer wanted to limit the scope of where the
> identifier will be used, just like any other declaration. Is
> there reason to believe his readers are confused on this point?
> I don't see any reason a priori to expect they will be.


Well, it would surprise me. (I did not say "confuse", though I accept
that the distinction is small but it's not insignificant). I'd wonder
why. Is the author doing some trick to use printf for some other
purpose in other scopes? Some of these could be causing a problem (UB)
so I might waste time checking to be sure.

>> Note that you posted here to ask. A good proportion of people
>> reading your code will not know the answer either. Do you want
>> them to be puzzled (or to have to take your /* honest, it's
>> legal! */ comment at face value)?

>
> Oh, but his question is a little bit different, namely, is this
> the right way to write the declaration?


And I answered that some time ago with a clear "yes". The discussion
has moved on (or at least I thought it had) to the merits of doing this,
rather than it's correctness.

> The readers don't need
> to worry (and probably won't worry) about that question, since
> he is giving them (presumably) a working program.


I often end up looking at code because it's not working. If everyone
only ever looked at code that works, programming guidelines would be
very different, I think. The need for clarity would be driven mainly by
the desire to facilitate improvements and modifications rather than to
save time when chasing down porting bugs.

> It's possible
> of course that some of them will wonder about whether it's legal,
> and take the trouble to find out, but that doesn't strike me as
> a bad thing; it's only when unwary readers are confused that I
> think some sort of advisory is called for, but to me that doesn't
> seem to be the case here.


This puzzles me a bit. Taken in abstract, I can't form any view of who
might end up reading code, written by the OP, based on this advice.

Taken in context, I don't think it matters since the post is almost
certainly coursework. Exactly this question has been posted here at
least three times since 2001. In light of that, the OP's summary --
"correct by not optimal" -- is not a bad answer in my view.

--
Ben.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-22-2012
Tim Rentsch <(E-Mail Removed)> writes:
> Keith Thompson <(E-Mail Removed)> writes:

[...]
> The call is UB because of 6.5.2.3 p9.


You mean 6.5.2.2 p9.

If the function [in a function call] is defined with a type
that is not compatible with the type (of the expression)
pointed to by the expression that denotes the called function,
the behavior is undefined.

> The declaration is UB because of 6.2.7 p2.


All declarations that refer to the same object or function
shall have compatible type; otherwise, the behavior is undefined.

> Because printf() is called, 6.9 p5 requires that printf() be
> defined (or else UB).


An *external definition* is an external declaration that is also
a definition of a function (other than an inline definition)
or an object. If an identifier declared with external linkage
is used in an expression (other than as part of the operand
of a sizeof or _Alignof operator whose result is an integer
constant), somewhere in the entire program there shall be
exactly one external definition for the identifier; otherwise,
there shall be no more than one.

(Providing copy-and-paste for the benefit of those who don't want to
take the time to look up the references -- though I suspect the
intersection with the set of those who are still following this may be
very small.)

[...]

> I am perfectly okay with different people having different opinions
> on points of style. Generally I try to avoid style battles whenever
> possible. What bothered me, I think, was so many people focusing on
> the style concerns at the expense of what the OP really was trying to
> ask about. I feel like his questions, and what intentions motivated
> those questions, got lost in the noise of giving style advice. As
> long as that point is addressed, clearly and distinctly, I'm okay
> with however much emphasis people want to give on the style issues;
> in fact how much style concerns are emphasized is itself a kind of
> style issue. On this particular issue I think our goals are actually
> not that far apart; where we may differ is in what approach will
> most help achieve those goals. You might be interested to know that
> partly I was inspired by an aphorism from another posting of yours
> (on a different topic, not that that matters), which was "when in
> doubt, learn the rules, thereby removing the doubt" (or something
> along those lines anyway). I think that's an excellent aphorism,
> and was pleased that OP had (unconsciously) adopted it.


That's pretty cool; I forget that I had written that. }

On the other hand, I've sometimes offered contrary advice.
For example, I find it easier to avoid defining identifiers starting
with underscores than to keep track of the cases where they can be
defined safely. And similarly, I'd rather #include standard headers
(and advise others to do so) than figure out when and whether I
can safely declare standard functions myself.

I mentioned recently that the C standard library is not a model of
consistency. I follow in its footsteps.

> I hope you've enjoyed my comments even if we haven't yet
> reached 100% agreement.


Absolutely.

--
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
 
 
 
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
Can a static function declaration conflict with a non-static declaration? nospam_timur@tabi.org C Programming 4 12-12-2006 10:26 PM
maxplusII error: a deferred constant declaration without a full declaration is not supported Noah VHDL 5 04-07-2006 02:34 PM
"virtual outside class declaration" and "declaration does not declare anything" kelvSYC C++ 6 05-17-2005 08:58 AM
Function declaration in class declaration Ovidesvideo C++ 4 12-10-2004 06:36 PM
Intel C++ 8.0 : declaration hides declaration Alex Vinokur C++ 4 04-05-2004 09:49 PM



Advertisments