Topic: declarations in the scope of prototypes
Author: giecrilj@stegny.2a.pl ("Kristof Zelechovski")
Date: Tue, 29 Aug 2006 23:18:57 GMT Raw View
Uzytkownik "ThosRTanner" <ttanner2@bloomberg.net> napisal w wiadomosci
news:1156406081.000791.153770@h48g2000cwc.googlegroups.com...
>
> Bronek Kozicki wrote:
>> kuyper@wizard.net wrote:
>> > I'm not sure precisely which check you want it to perform.
>>
>> it seems to me that OP wants to ban overloading, so that if library
>> header contains declaration:
>>
>> int fred(const int *b);
>>
>> .. the compiler won't allow definition of another function:
>>
>> int fred(int *b) { ... }
>>
>> in the library definition files. Currently such mistake is best detected
>> with the help of linker.
> No, I don't want to ban overloading. I want the compiler to detect
> declaration of a function for which there isn't a prototype in scope.
> It is questionable programming practice, especially if said function is
> unused elsewhere in the code. It will generate a link error if you use
> the prototype which the function is meant to be implementing.
>
Actually, it is worse than that. If you override a virtual function and
change the declaration of the function in the base class during maintenance,
the code compiles and links but it breaks miserably at run-time. I am sure
that explicit overrides must have already been proposed (they are in
Microsoft's managed C++, for example) as they are extremely useful - you
declare that the member function of derived class overrides the
implementation of the nase class and the code is ill-formed if there is no
corresponding declaration in the base class - but I do not know the status
of the proposition.
Chris
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Fri, 25 Aug 2006 11:23:13 CST Raw View
ThosRTanner wrote:
> kuyper@wizard.net wrote:
.
> > The reason why this code isn't permitted has nothing to do with it
> > being "in the context of a prototype". The only prototype in this
> > example is the one for wibble(), and the fact that this call to fred()
> > occurs in the context of that prototype has nothing to do with the fact
> > that it won't compile. The reason it won't compile is that it's NOT in
> > the scope of a suitably-defined prototype for fred().
>
> I thought that is what I said.
Nope, what you said is "in the context" rather than "outside the
scope". Since you've indicated that you used "context" to mean "scope",
that's exactly backwards from what you meant to say.
.
> Sorry - I have severe humpty-dumpty-itis. I know what I mean when I
> write something, and sometimes I'm not aware other people might use the
> same words differently.
On this newsgroup, until you get sufficiently fluent in standardese
you'll feel, and cause, a lot of confusion.
.
> > It would be fairer to make the comparision entirely within a class
> > definition:
> >
> > class Fred{
> > public:
> > void thisfunc(int* a) {/*function details*/};
> > void thisfunc(int const*a) {/*function details*/};
> > }
> >
> > That code will compile, and for precisely the same reason why similar
> > code outside of a class definition will also compile. What you've
> > demonstrated is the fact that a class definition cannot be re-opened.
> > It's still perfectly legal to add new member functions to a class,
> > without having previously declared them, as long as it's done inside
> > the class definition..
>
> Mr Coding Standard, he say, thou shalt not implement functions inside
> class declarations. So I tend not to do that. But I see your point.
I agree with that coding guideline, at least for non-trivial functions.
I only put the member function definitions in the class definition to
make the parallel clearer.
.
> > I think that requiring a non-defining prototype to be declared for
> > every function prior to it's definition is an idea with some merit.
> > However, as you say, it would indeed cause lots of existing code to
> > break. At a minimum, I'd recommend limiting it to non-static functions
> > that aren't defined in the unnamed namespace. Even better would be a
> > restricting that requirement to functions whose definition overloads an
> > existing function name with no previously declared function signature
> > that matches the new definition.
>
> Yes, that sounds good. I can see it's going down like a lead balloon on
> the newsgroup at the moment though!
With the restrictions I've suggested, it's not likely to break as much
code as the unrestricted version of this proposal would, which is the
main objection other people have.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Sat, 26 Aug 2006 09:15:25 CST Raw View
kuyper@wizard.net wrote:
> > Yes, that sounds good. I can see it's going down like a lead balloon on
> > the newsgroup at the moment though!
>
> With the restrictions I've suggested, it's not likely to break as much
> code as the unrestricted version of this proposal would, which is the
> main objection other people have.
>
I still breaks far too much code.
I've downloaded ten projects here (mainly the first ten projects in the
order of the page, except I've not downloaded the huge projects because
I've a slow connection)
http://freshmeat.net/browse/165/
Your proposal, with all the restrictions, breaks 8/10 of these
projects:
tightvnc : ClearKeyState in winvnc/vncClient.cpp
Galleon : __builtin_vec_new and other functions in
src/mozilla/gcc2abi.cpp
K3B : no problem detected.
fwbuilder: guessExecPath in src/common/init.cpp
mozilla : TryConnect in
mozilla/ipc/ipcd/client/src/ipcConnectionUnix.cpp
centericq: stragerange in src/icqdialogs.cc
ncurses : no problem detected.
audacity : wxOnAssert in src/AudacityApp.cpp
scribus : mymkdir & several others in scribus/fileunzip.cpp
fluxbox : doSkipWindow in src/FocusControl.cc
It is probably not representative of the whole code base on the earth,
but I think it gives an idea of how much code it can break (the real
number might be > 80% or < 80%, but is probably huge)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Wed, 23 Aug 2006 09:37:24 CST Raw View
Given that this:
int a = fred();
isn't permitted in the context of a prototype, it is sometimes
extremely annoying that
int fred(int *b) { ... }
is permitted without a prototype. Especially when fred is part of a
library, and there is a prototype for it - that says int fred(int const
*b). So the thing compiles away happily and you don't get an error till
you link.
I am aware that changing this would force people to declare prototypes
for ALL their functions, and would this be not allowed because it would
break existing working code, etc, etc.
Nonetheless it would be extremely helpful when developing a library to
have some sort of keyword or option in the language to get this check
done at compile time, not at link time.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Wed, 23 Aug 2006 11:14:05 CST Raw View
ThosRTanner wrote:
> Given that this:
>
> int a = fred();
>
> isn't permitted in the context of a prototype,
I'm not sure what you mean by "in the context of a prototype". My first
guess would be that you're using "context" as a synonym for "scope",
but if there's a prototype for fred() which is in scope, which has no
arguments other than ones with a default value, and if the return type
declared in that prototype is implicitly convertible to int, the above
code is permitted. If there's a prototype for fred in scope that
doesn't have those characteristics, you're right - it is not permitted,
and rightly so.
> ... it is sometimes
> extremely annoying that
>
> int fred(int *b) { ... }
>
> is permitted without a prototype.
Again, I'm not sure what you're saying. The first part of that
declaration (the part prior to the '{') IS a prototype, so no other
prototypes are required.
> ... Especially when fred is part of a
> library, and there is a prototype for it - that says int fred(int const
> *b). So the thing compiles away happily and you don't get an error till
> you link.
>
> I am aware that changing this would force people to declare prototypes
> for ALL their functions, and would this be not allowed because it would
> break existing working code, etc, etc.
It's not possible to define a function without declaring a prototype
for it, because a function prototype is an inherent, unremovable
portion of the function definition syntax. Unlike C, C++ doesn't allow
calls to functions that haven't been prototyped. Therefore, I'm not
sure exactly what it is you're proposing to change.
> Nonetheless it would be extremely helpful when developing a library to
> have some sort of keyword or option in the language to get this check
> done at compile time, not at link time.
I'm not sure precisely which check you want it to perform.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Jiang" <goo.mail01@yahoo.com>
Date: Wed, 23 Aug 2006 11:16:37 CST Raw View
ThosRTanner wrote:
> Given that this:
>
> int a = fred();
>
> isn't permitted in the context of a prototype, it is sometimes
> extremely annoying that
>
> int fred(int *b) { ... }
>
> is permitted without a prototype. Especially when fred is part of a
> library, and there is a prototype for it - that says int fred(int const
> *b). So the thing compiles away happily and you don't get an error till
> you link.
>
For your example,
extern int foo(const int* p); // you tell the compiler there
// will be a definition somewhere
int foo(int* p){} // this definition is actually ignored
int main()
{
const int i = 0;
foo(&i); // OK, since we do have a prototype.
}
I do not think it is compiler's job to issue error for you here,
since the compiler will never know when and where function
void foo(const int* p)
is defined using our current multi-TUs compilation model.
Or, you mean something else?
> I am aware that changing this would force people to declare prototypes
> for ALL their functions, and would this be not allowed because it would
> break existing working code, etc, etc.
>
But the C++ language do require you declare prototype.
> Nonetheless it would be extremely helpful when developing a library to
> have some sort of keyword or option in the language to get this check
> done at compile time, not at link time.
>
How could this be possible?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: brok@spam-trap-cop.net (Bronek Kozicki)
Date: Wed, 23 Aug 2006 18:29:52 GMT Raw View
kuyper@wizard.net wrote:
> I'm not sure precisely which check you want it to perform.
it seems to me that OP wants to ban overloading, so that if library
header contains declaration:
int fred(const int *b);
.. the compiler won't allow definition of another function:
int fred(int *b) { ... }
in the library definition files. Currently such mistake is best detected
with the help of linker.
IMHO, this is rather silly request - the code in question should be
tested before shipping, and any useful form of testing would reveal such
error.
B.
--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Victor Bazarov" <v.Abazarov@comAcast.com>
Date: Wed, 23 Aug 2006 21:05:12 CST Raw View
ThosRTanner wrote:
> Given that this:
>
> int a = fred();
>
> isn't permitted in the context of a prototype,
What is "the context of a prototype"? Do you mean in the global scope?
It *is* permitted, given that 'fred' has been defined.
> it is sometimes
> extremely annoying that
>
> int fred(int *b) { ... }
>
> is permitted without a prototype.
Huh? The line you've given *is* a prototype (since every definition
is also a declaration).
> Especially when fred is part of a
> library, and there is a prototype for it - that says int fred(int
> const *b).
It's not a prototype for *it*, it's a prototype (declaration) for
a different function. The name 'fred' is then considered "overloaded".
Either you aren't aware of overloading or you're pulling our combined
leg here.
> So the thing compiles away happily and you don't get an
> error till you link.
What error? If you declare a function, but don't use it, you don't
need to define it (unless it's a virtual function not declared pure).
> I am aware that changing this would force people to declare prototypes
> for ALL their functions, and would this be not allowed because it
> would break existing working code, etc, etc.
Huh?
> Nonetheless it would be extremely helpful when developing a library to
> have some sort of keyword or option in the language to get this check
> done at compile time, not at link time.
What kind of check? It is perfectly normal if I write
void foo(int*);
void foo(int const*);
because both of them are valid and besides, they happily co-exist.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: brok@spam-trap-net.com (Bronek Kozicki)
Date: Thu, 24 Aug 2006 02:06:11 GMT Raw View
Bronek Kozicki wrote:
> it seems to me that OP wants to ban overloading, so that if library
> header contains declaration:
>
> int fred(const int *b);
>
> .. the compiler won't allow definition of another function:
>
> int fred(int *b) { ... }
>
> in the library definition files.
it just occured to me that C++ does have similar feature, it's called extern "C" :
extern "C" int fred(const int *b);
extern "C" int fred(int *b) {return *b;}
int main()
{
const int a = 0;
return fred(&a);
}
compilation will fail.
B.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Thu, 24 Aug 2006 09:52:18 CST Raw View
Bronek Kozicki wrote:
> kuyper@wizard.net wrote:
> > I'm not sure precisely which check you want it to perform.
>
> it seems to me that OP wants to ban overloading, so that if library
> header contains declaration:
>
> int fred(const int *b);
>
> .. the compiler won't allow definition of another function:
>
> int fred(int *b) { ... }
>
> in the library definition files. Currently such mistake is best detected
> with the help of linker.
No, I don't want to ban overloading. I want the compiler to detect
declaration of a function for which there isn't a prototype in scope.
It is questionable programming practice, especially if said function is
unused elsewhere in the code. It will generate a link error if you use
the prototype which the function is meant to be implementing.
> IMHO, this is rather silly request - the code in question should be
> tested before shipping, and any useful form of testing would reveal such
> error.
>
The code won't link, so it's unlikely to ship. However, the earlier an
issue is detected, the easier it is to fix it. And an issue detected at
compile time will be easier to fix than an issue detected at link time
(I know this is true, I speak from painful experience).
IMHO it is rather silly to say that issues that can be detected by the
compiler should be ignored and left to discover at the testing stage,
given the huge mass of evidence that the later an issue is found, the
more expensive it is to fix.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "AllanW" <allan_w@my-dejanews.com>
Date: Thu, 24 Aug 2006 10:00:02 CST Raw View
Bronek Kozicki wrote:
> kuyper@wizard.net wrote:
> > I'm not sure precisely which check you want it to perform.
>
> it seems to me that OP wants to ban overloading,
It's clear to me that this is NOT what the OP meant.
Possibly the OP was not aware of overloading, but more likely
he just wasn't referring to it.
> so that if library header contains declaration:
> int fred(const int *b);
> .. the compiler won't allow definition of another function:
> int fred(int *b) { ... }
> in the library definition files.
Right. I think that he would like this to remain legal:
// foo.h
int foo(int*a);
int foo(const int*a);
// foo.cpp
int foo(int*a) { ... do something ... }
int foo(const int*a) { ... do something else ... }
And maybe even this:
// No header file
int bar(int*a) { ... do something ... }
int bar(const int*a) { ... do something else ... }
But he wants to disallow this:
// baz.h
// This is supposed to be the one-and-only prototype
int baz(const int*a);
// baz.cpp
// But this doesn't match
int baz(int*a) { ... do something ... }
> Currently such mistake is best detected with the help of linker.
Right. I think the OP is suggesting that a function shouldn't
compile it doesn't already have a prototype, but it overloads
a function that does have a prototype but doesn't yet have
a definition.
He's quite right that this would break existing working code,
but it probably isn't very good code.
On the other hand, if the error is caught... is it really
important WHERE it is caught? I guess it is...
compiler error messages are more helpful than linker
error messages... compiler messages have specific line
numbers, and linker messages don't...
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Thu, 24 Aug 2006 10:04:12 CST Raw View
ThosRTanner wrote:
> Given that this:
>
> int a = fred();
>
> isn't permitted in the context of a prototype, it is sometimes
> extremely annoying that
>
> int fred(int *b) { ... }
>
> is permitted without a prototype. Especially when fred is part of a
> library, and there is a prototype for it - that says int fred(int const
> *b). So the thing compiles away happily and you don't get an error till
> you link.
>
> I am aware that changing this would force people to declare prototypes
> for ALL their functions, and would this be not allowed because it would
> break existing working code, etc, etc.
I agree that requiring that every (non-static) function be prototyped
before it is defined is quite useful; but this behavior is best
implemented as a C++ compiler option and not as a language requirement
(for the reasons cited above). Besides, having this option added to
your current compiler (if it does not support it already) is likely to
be more effective (and no doubt more expedient) than successfully
gettting this kind of change into the C++ standard.
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Thu, 24 Aug 2006 10:18:06 CST Raw View
Victor Bazarov wrote:
> ThosRTanner wrote:
> > Given that this:
> >
> > int a = fred();
> >
> > isn't permitted in the context of a prototype,
>
> What is "the context of a prototype"? Do you mean in the global scope?
For context, read scope, sorry.
> It *is* permitted, given that 'fred' has been defined.
The point is "given that fred has been defined" - if it hasn't, it
won't.
The following entire file:
int wibble()
{
int a = fred();
return a;
}
won't compile, because the compiler doesn't have a definition for
fred.
However, this file will compile
int wibble()
{
return 1;
}
So will this pair of files:
wibble.hh
int wibble(const *int);
wibble.cc
#include "wibble.hh"
int wibble(int *a) { return a; }
However, the above 2 files plus this will compile but won't link
main.cc
#include "wibble.hh"
int main() { int a = 1; return wibble(&a) };
I realise this is a silly and highly trivial example. However, it
occurs frequently enough and sometimes trying to work out why the
linker is giving an error is not trivial.
> > it is sometimes
> > extremely annoying that
> >
> > int fred(int *b) { ... }
> >
> > is permitted without a prototype.
>
> Huh? The line you've given *is* a prototype (since every definition
> is also a declaration).
I don't think that is a helpful concept. Although currently the
definition of fred(int *) is considered to be also a declaration, it
leads to errors at link time which could have been detected at compile
time.
> > Especially when fred is part of a
> > library, and there is a prototype for it - that says int fred(int
> > const *b).
>
> It's not a prototype for *it*, it's a prototype (declaration) for
> a different function. The name 'fred' is then considered "overloaded".
> Either you aren't aware of overloading or you're pulling our combined
> leg here.
I'm aware of overloading, thank you, and I am not pulling your leg.
Missing a function in a library that doesn't match any prototypes in
the headers will eventually be detected at link time. I feel it should
be detected and detectable at compile time.
> > So the thing compiles away happily and you don't get an
> > error till you link.
>
> What error? If you declare a function, but don't use it, you don't
> need to define it (unless it's a virtual function not declared pure).
Why should one wish to declare a function that is unusable? You can't
do it in a class. This:
class Fred { public: void thisfunc(int *a); };
Fred::thisfunc(int const *a) { ...}
won't compile.
Why then should the compiler let it pass because the function isn't in
a class?
> > I am aware that changing this would force people to declare prototypes
> > for ALL their functions, and would this be not allowed because it
> > would break existing working code, etc, etc.
>
> Huh?
Well it would break existing code, wouldn't it. This:
int fred(void) { .... }
int main() { return fred(); }
would stop compiling.
> > Nonetheless it would be extremely helpful when developing a library to
> > have some sort of keyword or option in the language to get this check
> > done at compile time, not at link time.
>
> What kind of check? It is perfectly normal if I write
>
> void foo(int*);
> void foo(int const*);
>
> because both of them are valid and besides, they happily co-exist.
I don't have a problem with that.
My problem is with when you have a prototype for a function but you
implement the function with the wrong declaration, for which there is
no prototype in scope. If nothing else, it is questionable programming
practice, because the function can never be used (without invoking even
worse practices).
At least requiring a non-fatal diagnostic when this (a function which
satisfies no prototype and is never used subsequently) is detected
would be helpful.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Thu, 24 Aug 2006 10:23:39 CST Raw View
Victor Bazarov wrote:
> ThosRTanner wrote:
> > Given that this:
> >
> > int a = fred();
> >
> > isn't permitted in the context of a prototype,
>
> What is "the context of a prototype"? Do you mean in the global scope?
> It *is* permitted, given that 'fred' has been defined.
>
> > it is sometimes
> > extremely annoying that
> >
> > int fred(int *b) { ... }
> >
> > is permitted without a prototype.
>
> Huh? The line you've given *is* a prototype (since every definition
> is also a declaration).
>
I guess (but I'm not sure) that the OP wants that definitions loose
their property of being declarations, and than any definition require a
declaration in addition to the fact (which is already true) that any
usage of a function requires a declaration.
I guess the OP was confusing the terms "prototype" and
"declaration-which-is-not-a-definition"
Which would mean that:
void f(char*);
void f(const char*) { // error f(const char*) not declared
}
Another example:
void func(char*);
void fucn(char*) { // note that func is mispelled : error fucn(char*)
not declared
}
Yet another example:
void func(char*) { // error f(char*) not declared
}
And:
void f(char*);
void f(char*) { // ok, f(char*) has been declared before being defined.
}
A final example:
void f(const char*);
void f(char*);
void f(char*) { // ok
}
void f(const char*) { // ok
}
It would mainly reveal at compile time errors that would be revealed at
link time (such as mispelling)
I don't really see the point, but I think that it's the request of the
OP (please correct me if I guess wrong).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Victor Bazarov" <v.Abazarov@comAcast.net>
Date: Thu, 24 Aug 2006 11:15:49 CST Raw View
SuperKoko wrote:
> [..]
> I guess (but I'm not sure) that the OP wants that definitions loose
> their property of being declarations, and than any definition require
> a declaration in addition to the fact (which is already true) that any
> usage of a function requires a declaration.
> [..]
> It would mainly reveal at compile time errors that would be revealed
> at link time (such as mispelling)
> I don't really see the point, but I think that it's the request of the
> OP (please correct me if I guess wrong).
If you're right, and that's what the OP actually wants, then he's SOL:
it's not gonna happen. Compile-time errors instead of link errors for
stand-alone functions are not a compelling enough reason to break the
code all over the world that relies on every definition to alse be
a declaration.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Thu, 24 Aug 2006 11:38:26 CST Raw View
Jiang wrote:
> ThosRTanner wrote:
> > Given that this:
> >
> > int a = fred();
> >
> > isn't permitted in the context of a prototype, it is sometimes
> > extremely annoying that
> >
> > int fred(int *b) { ... }
> >
> > is permitted without a prototype. Especially when fred is part of a
> > library, and there is a prototype for it - that says int fred(int const
> > *b). So the thing compiles away happily and you don't get an error till
> > you link.
> >
>
> For your example,
>
> extern int foo(const int* p); // you tell the compiler there
> // will be a definition somewhere
I would contend that that extern being outside a header file is
actually fairly bad programming practice anyway, as if you change the
actual definition of foo, you'll have problems.
> int foo(int* p){} // this definition is actually ignored
> int main()
> {
> const int i = 0;
> foo(&i); // OK, since we do have a prototype.
> }
At the end of this, the compiler should have been able to spot that you
have a definition for int foo(int *p), and there was no prototype for
it. This is highly likely to be an error.
> I do not think it is compiler's job to issue error for you here,
> since the compiler will never know when and where function
> is defined using our current multi-TUs compilation model.
Well, it does know that the function is defined, and there is no
prototype for it in scope, so, nobody can access it without
constructing their own prototype (and probably getting it wrong if my
experience is anything to go by). This is at least a dubious way to go
about things.
> Or, you mean something else?
>
> > I am aware that changing this would force people to declare prototypes
> > for ALL their functions, and would this be not allowed because it would
> > break existing working code, etc, etc.
> >
>
> But the C++ language do require you declare prototype.
Well, no, it doesn't require a prototype for a function declaration, it
treats a function declaration as a prototype. I'm just not convinced of
the benefits of that.
> > Nonetheless it would be extremely helpful when developing a library to
> > have some sort of keyword or option in the language to get this check
> > done at compile time, not at link time.
> >
>
> How could this be possible?
Any of the following:
a) a requirement that the compiler should issue a warning diagnostic if
a function is declared for which there is no prototype in scope
[possibly only if the function is subsequently unused] - wouldn't break
existing code. It is trivial for a compiler to detect this situation.
b) a requirement that the compiler should ditto ditto, but the
diagnostic would be fatal.
c) make 'extern' require that there be a prototype in scope.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Thu, 24 Aug 2006 16:40:21 GMT Raw View
In article <1156330585.524691.300240@i3g2000cwc.googlegroups.com>,
ThosRTanner <ttanner2@bloomberg.net> writes
>Given that this:
>
> int a = fred();
>
>isn't permitted in the context of a prototype, it is sometimes
>extremely annoying that
Strictly speaking there are no such things as prototypes in C++. There
are functions declarations that are not also definitions and function
definitions that are necessarily declarations.
The term prototype was introduced to C to distinguish between the two
forms of function declaration that C permits. C++ dropped the earlier
form and so made a minor simplification.
For example:
In C:
void foo();
declares foo to be a function with an unspecified parameter list. In C++
it explicitly specifies a function that is called without arguments. C
has to get up to a syntactic trick to cater for that case:
void foo(void);
--
Francis Glassborow ACCU
Author of 'You Can Do It!' and "You Can Program in C++"
see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: kuyper@wizard.net
Date: Thu, 24 Aug 2006 12:19:11 CST Raw View
ThosRTanner wrote:
> Victor Bazarov wrote:
> > ThosRTanner wrote:
> > > Given that this:
> > >
> > > int a = fred();
> > >
> > > isn't permitted in the context of a prototype,
> >
> > What is "the context of a prototype"? Do you mean in the global scope?
> For context, read scope, sorry.
>
> > It *is* permitted, given that 'fred' has been defined.
> The point is "given that fred has been defined" - if it hasn't, it
> won't.
>
> The following entire file:
> int wibble()
> {
> int a = fred();
> return a;
> }
>
> won't compile, because the compiler doesn't have a definition for
> fred.
The reason why this code isn't permitted has nothing to do with it
being "in the context of a prototype". The only prototype in this
example is the one for wibble(), and the fact that this call to fred()
occurs in the context of that prototype has nothing to do with the fact
that it won't compile. The reason it won't compile is that it's NOT in
the scope of a suitably-defined prototype for fred().
> However, this file will compile
> int wibble()
> {
> return 1;
> }
>
> So will this pair of files:
> wibble.hh
> int wibble(const *int);
> wibble.cc
> #include "wibble.hh"
> int wibble(int *a) { return a; }
>
> However, the above 2 files plus this will compile but won't link
> main.cc
> #include "wibble.hh"
> int main() { int a = 1; return wibble(&a) };
>
> I realise this is a silly and highly trivial example. However, it
> occurs frequently enough and sometimes trying to work out why the
> linker is giving an error is not trivial.
I agree that this is a problem. You should have put it in those terms
in your first message.
.
> Why should one wish to declare a function that is unusable? You can't
> do it in a class. This:
>
> class Fred { public: void thisfunc(int *a); };
> Fred::thisfunc(int const *a) { ...}
>
> won't compile.
It would be fairer to make the comparision entirely within a class
definition:
class Fred{
public:
void thisfunc(int* a) {/*function details*/};
void thisfunc(int const*a) {/*function details*/};
}
That code will compile, and for precisely the same reason why similar
code outside of a class definition will also compile. What you've
demonstrated is the fact that a class definition cannot be re-opened.
It's still perfectly legal to add new member functions to a class,
without having previously declared them, as long as it's done inside
the class definition..
> > > I am aware that changing this would force people to declare prototypes
> > > for ALL their functions, and would this be not allowed because it
> > > would break existing working code, etc, etc.
> >
> > Huh?
>
> Well it would break existing code, wouldn't it. This:
> int fred(void) { .... }
>
> int main() { return fred(); }
>
> would stop compiling.
It wasn't clear that you were proposing that function definitions not
count as function prototypes. Under current rules, that code does
declare a prototype for every function it contains, so it wasn't clear
from the wording that you were using that you were proposing a change
that would invalidate it.
> My problem is with when you have a prototype for a function but you
> implement the function with the wrong declaration, for which there is
> no prototype in scope. ...
For the sake of not confusing people, I'd recommend re-writing
sentences like that one to conform to the current handling of function
definitions, rather than your proposed change. Change "no prototype in
scope" to "no prior prototype in scope".
> ... If nothing else, it is questionable programming
> practice, because the function can never be used (without invoking even
> worse practices).
It can be used without any problems anywhere in the same translation
unit after the point of definition, and I don't consider that to be a
questionable programming practice. I do it all the time; usually only
with static functions or functions defined in the unnamed namespace, of
course. While I can see some point in what you're proposing, I wouldn't
want it to be implemented in a way that would render such practices
illegal.
I think that requiring a non-defining prototype to be declared for
every function prior to it's definition is an idea with some merit.
However, as you say, it would indeed cause lots of existing code to
break. At a minimum, I'd recommend limiting it to non-static functions
that aren't defined in the unnamed namespace. Even better would be a
restricting that requirement to functions whose definition overloads an
existing function name with no previously declared function signature
that matches the new definition.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "Victor Bazarov" <v.Abazarov@comAcast.net>
Date: Thu, 24 Aug 2006 13:19:35 CST Raw View
kuyper@wizard.net wrote:
> [...let's introduce the requirement when all functions have
> to have a declaration before even the definition is compiled...]
> it would indeed cause lots of existing code to
> break. At a minimum, I'd recommend limiting it to non-static functions
> that aren't defined in the unnamed namespace. Even better would be a
> restricting that requirement to functions whose definition overloads
> an existing function name with no previously declared function
> signature that matches the new definition.
I think the OP should request from the compiler vendors to introduce
some kind of a warning issued in that case. Trying to make such drastic
change that would break tons of code is simply a waste of time.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: brok@spam-trap-cop.net ("Bronek Kozicki")
Date: Fri, 25 Aug 2006 00:55:49 GMT Raw View
AllanW <allan_w@my-dejanews.com> wrote:
> But he wants to disallow this:
>
> // baz.h
> // This is supposed to be the one-and-only prototype
> int baz(const int*a);
>
> // baz.cpp
> // But this doesn't match
> int baz(int*a) { ... do something ... }
it is just a specific and useful form of overloading. Nevertheless, I
suggest using extern "C" .
B.
--
Remove -trap- when replying. Usun -trap- gdy odpisujesz.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "ThosRTanner" <ttanner2@bloomberg.net>
Date: Fri, 25 Aug 2006 09:59:52 CST Raw View
kuyper@wizard.net wrote:
> ThosRTanner wrote:
> > Victor Bazarov wrote:
> > > ThosRTanner wrote:
> > > > Given that this:
> > > >
> > > > int a = fred();
> > > >
> > > > isn't permitted in the context of a prototype,
> > >
> > > What is "the context of a prototype"? Do you mean in the global scope?
> > For context, read scope, sorry.
> >
> > > It *is* permitted, given that 'fred' has been defined.
> > The point is "given that fred has been defined" - if it hasn't, it
> > won't.
> >
> > The following entire file:
> > int wibble()
> > {
> > int a = fred();
> > return a;
> > }
> >
> > won't compile, because the compiler doesn't have a definition for
> > fred.
>
> The reason why this code isn't permitted has nothing to do with it
> being "in the context of a prototype". The only prototype in this
> example is the one for wibble(), and the fact that this call to fred()
> occurs in the context of that prototype has nothing to do with the fact
> that it won't compile. The reason it won't compile is that it's NOT in
> the scope of a suitably-defined prototype for fred().
I thought that is what I said.
> > However, this file will compile
> > int wibble()
> > {
> > return 1;
> > }
> >
> > So will this pair of files:
> > wibble.hh
> > int wibble(const *int);
> > wibble.cc
> > #include "wibble.hh"
> > int wibble(int *a) { return a; }
> >
> > However, the above 2 files plus this will compile but won't link
> > main.cc
> > #include "wibble.hh"
> > int main() { int a = 1; return wibble(&a) };
> >
> > I realise this is a silly and highly trivial example. However, it
> > occurs frequently enough and sometimes trying to work out why the
> > linker is giving an error is not trivial.
>
> I agree that this is a problem. You should have put it in those terms
> in your first message.
>
Sorry - I have severe humpty-dumpty-itis. I know what I mean when I
write something, and sometimes I'm not aware other people might use the
same words differently.
> > Why should one wish to declare a function that is unusable? You can't
> > do it in a class. This:
> >
> > class Fred { public: void thisfunc(int *a); };
> > Fred::thisfunc(int const *a) { ...}
> >
> > won't compile.
>
> It would be fairer to make the comparision entirely within a class
> definition:
>
> class Fred{
> public:
> void thisfunc(int* a) {/*function details*/};
> void thisfunc(int const*a) {/*function details*/};
> }
>
> That code will compile, and for precisely the same reason why similar
> code outside of a class definition will also compile. What you've
> demonstrated is the fact that a class definition cannot be re-opened.
> It's still perfectly legal to add new member functions to a class,
> without having previously declared them, as long as it's done inside
> the class definition..
Mr Coding Standard, he say, thou shalt not implement functions inside
class declarations. So I tend not to do that. But I see your point.
> > > > I am aware that changing this would force people to declare prototypes
> > > > for ALL their functions, and would this be not allowed because it
> > > > would break existing working code, etc, etc.
> > >
> > > Huh?
> >
> > Well it would break existing code, wouldn't it. This:
> > int fred(void) { .... }
> >
> > int main() { return fred(); }
> >
> > would stop compiling.
>
> It wasn't clear that you were proposing that function definitions not
> count as function prototypes. Under current rules, that code does
> declare a prototype for every function it contains, so it wasn't clear
> from the wording that you were using that you were proposing a change
> that would invalidate it.
Well, I wasn't quite sure that is what I was proposing, but yes.
> > My problem is with when you have a prototype for a function but you
> > implement the function with the wrong declaration, for which there is
> > no prototype in scope. ...
>
> For the sake of not confusing people, I'd recommend re-writing
> sentences like that one to conform to the current handling of function
> definitions, rather than your proposed change. Change "no prototype in
> scope" to "no prior prototype in scope".
Right
> > ... If nothing else, it is questionable programming
> > practice, because the function can never be used (without invoking even
> > worse practices).
>
> It can be used without any problems anywhere in the same translation
> unit after the point of definition, and I don't consider that to be a
> questionable programming practice.
Umm, no. It's clearly far less of an issue with static and functions in
the unnamed namespace.
> I do it all the time; usually only
> with static functions or functions defined in the unnamed namespace, of
> course. While I can see some point in what you're proposing, I wouldn't
> want it to be implemented in a way that would render such practices
> illegal.
Sure. I really only wanted to cover external misdefinitions.
> I think that requiring a non-defining prototype to be declared for
> every function prior to it's definition is an idea with some merit.
> However, as you say, it would indeed cause lots of existing code to
> break. At a minimum, I'd recommend limiting it to non-static functions
> that aren't defined in the unnamed namespace. Even better would be a
> restricting that requirement to functions whose definition overloads an
> existing function name with no previously declared function signature
> that matches the new definition.
Yes, that sounds good. I can see it's going down like a lead balloon on
the newsgroup at the moment though!
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "kanze" <kanze@gabi-soft.fr>
Date: Fri, 25 Aug 2006 10:02:10 CST Raw View
Greg Herlihy wrote:
> ThosRTanner wrote:
> > Given that this:
> > int a = fred();
> > isn't permitted in the context of a prototype, it is sometimes
> > extremely annoying that
> > int fred(int *b) { ... }
> > is permitted without a prototype. Especially when fred is
> > part of a library, and there is a prototype for it - that
> > says int fred(int const *b). So the thing compiles away
> > happily and you don't get an error till you link.
> > I am aware that changing this would force people to declare
> > prototypes for ALL their functions, and would this be not
> > allowed because it would break existing working code, etc,
> > etc.
> I agree that requiring that every (non-static) function be
> prototyped before it is defined is quite useful;
Non static AND not in an anonymous namespace.
Formally, of course, this would be expressed as requiring a
non-defining prototype to appear before the definition of a
function. Something like:
A function definition is only legal if one of the following
are true:
-- the function has already been declared,
-- the name of the function has internal binding, or
-- the function is in the anonymous namespace.
-- the is inline
-- the "function" is a non-exported function template
The last two seem reasonable exceptions as well, since the
definition of the function would normally be in the header file.
Of course, the conditions are becoming more and more
complicated. (And additional complications are not really
something that C++ needs.)
> but this behavior is best implemented as a C++ compiler option
Agreed. I don't think we can bar it, if only for backwards
compatibility reasons. Also, as mentionned above, the rules are
complicated enough that I'm not sure we can get them 100% right
the first time.
> and not as a language requirement (for the reasons cited
> above). Besides, having this option added to your current
> compiler (if it does not support it already) is likely to be
> more effective (and no doubt more expedient) than successfully
> gettting this kind of change into the C++ standard.
One would hope so. When was the last time your compiler vendor
listened to you with regards to options?
--
James Kanze GABI Software
Conseils en informatique orient e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S mard, 78210 St.-Cyr-l' cole, France, +33 (0)1 30 23 00 34
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: "SuperKoko" <tabkannaz@yahoo.fr>
Date: Fri, 25 Aug 2006 10:01:28 CST Raw View
ThosRTanner wrote:
> Victor Bazarov wrote:
> > ThosRTanner wrote:
> > > Given that this:
> > >
> > > int a = fred();
> > >
> > > isn't permitted in the context of a prototype,
> >
> > What is "the context of a prototype"? Do you mean in the global scope?
> For context, read scope, sorry.
>
> > It *is* permitted, given that 'fred' has been defined.
> The point is "given that fred has been defined" - if it hasn't, it
> won't.
>
> The following entire file:
> int wibble()
> {
> int a = fred();
> return a;
> }
>
> won't compile, because the compiler doesn't have a definition for
> fred.
>
> However, this file will compile
> int wibble()
> {
> return 1;
> }
>
> So will this pair of files:
> wibble.hh
> int wibble(const *int);
> wibble.cc
> #include "wibble.hh"
> int wibble(int *a) { return a; }
>
> However, the above 2 files plus this will compile but won't link
> main.cc
> #include "wibble.hh"
> int main() { int a = 1; return wibble(&a) };
>
> I realise this is a silly and highly trivial example. However, it
> occurs frequently enough and sometimes trying to work out why the
> linker is giving an error is not trivial.
>
Yes, a compiler error might speed up error correction.
However any modification of the C++ standard must be scientifically
appreciated for a benefit/tradeoff ratio.
First, assuming that your proposal only applies to external linkage
non-inline non-template functions outside of anonymous namespaces,
otherwise it would break perhaps more than 90% of the C++ code base.
The benefit is not big (it only helps correcting earlier some
non-runtime errors).
The tradeoff is huge : It would break perhaps more than 50% of the C++
code base.
Even if it is dubious practice, a huge code base use external linkage
where internal linkage or anonymous namespaces should be used (for
functions local to a module).
You know, there are much worse programming practices that are allowed
by the standard (such as deleting anything through a void* pointer
which has always UB unless the statement is *never* effectively
executed).
A smaller code base, but probably not negligible doesn't use headers
for very small modules (the function is defined as extern in the
module, without previous declaration, and is declared in modules that
want to import it).
> > > it is sometimes
> > > extremely annoying that
> > >
> > > int fred(int *b) { ... }
> > >
> > > is permitted without a prototype.
> >
> > Huh? The line you've given *is* a prototype (since every definition
> > is also a declaration).
>
> I don't think that is a helpful concept. Although currently the
> definition of fred(int *) is considered to be also a declaration, it
> leads to errors at link time which could have been detected at compile
> time.
>
Note that your proposal is not acceptable without the few corrections I
added (external linkage, non-inline, non-template, outside of an
anonymous namespace).
In fact, even with these corrections it is not acceptable at all
(breaks far too much code).
But, with these corrections, it doesn't "remove an unhelpful concept"
it adds particular restrictions to that "concept".
It doesn't simplify the language definition itself, it only complicates
it.
However language definition complexity is not the issue here...
Generally, C++ is not a simple language, and it's not a problem (C++
doesn't claim to be a "simple pure" language whose definition can be
written on a single A4 page)
Anyway, you are free to propose to your favorite compiler vendor to add
a warning message for that.
If your compiler vendor is nice and accepts suggestion, the next
version of your compiler might contain a new compilation flag to
activate this warning message.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]