type
TFoo ..... ;
PFoo = ^PFoo;
TFoo is a type, and PFoo is a pointer to a TFoo.
Or in C++
struct Foo .......;
typedef Foo* PFoo;
I've never actual seen this done in C++ much if at all. And I'm wondering if
it's just bad style, or wasted effort.. or what?
I have to be honest and say I find C++ pointer syntax a bit messy, and
figured doing this would clean it up a bit, but then it doesnt seem to be
somthing anyone does, and I'm wondering why.
thanks,
Is PFoo a big improvement over Foo* ? Any improvement?
On the other hand, if you look in Windows headers, you will find tons
of these! :-)
Bo Persson
I almost always typedef my pointers. It lets you create a type-safe
null values, for example PFoo( ). It also lets you switch between smart
and raw pointers at will, although doing so may require design changes.
>> TFoo ..... ;
>> PFoo = ^PFoo;
>
> Is PFoo a big improvement over Foo* ? Any improvement?
for me Foo* is definitely a pointer type, while PFoo might or might not,
since there are usually structures with a P in the first character.
> On the other hand, if you look in Windows headers, you will find tons
> of these! :-)
OS/2 too. :-)
These times IBM and Microsoft worked together.
Marcel
Are you sure it's not
PFoo = ^TFoo;
? Just checking... :-)
>
> TFoo is a type, and PFoo is a pointer to a TFoo.
> [..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
That's true; PFoo is an unfortunate abbreviation. How do you feel about
foo_pointer, though?
I think the difference is that in C++ you don't need this and in
Delphi you have to define a type like that in order to declare
variables. It's been a while since I programmed in Pascal but I think
function Foo(a : Integer; pb : ^Integer) : Integer
begin
Foo := a + pb^;
end;
is illegal because "^Integer" only works in a type declaration,
doesn't it? That would be a reason for why "type PBlah = ^TBlah;" is
so pupular --- it would be a necessity.
Correct me if I'm wrong.
Cheers!
SG
Yeah you're right ;)
Yeah, you're right too. I forgot about that.
But would they have the second letter capitalized?
Point vs PCoord, if you see what I mean.
What is the advantage over Foo* ?!
Bo Persson
1. You can write foo_pointer( ) instead of 0 or NULL, neither of which
have the correct static type. I realize I'm in the minority, but I
really don't see any purpose for NULL, 0, or nullptr.
2. You can more easily move the code into a template that takes the
pointer type as a parameter. If you hard-code the fact that you're
using raw pointers, then parameterizing the pointer type will be a royal
pain.
3. You can switch locally from one pointer type to another, e.g. from
foo* to shared_ptr<foo> within a given function, since an inner
foo_pointer can hide an outer one. Switching pointer types also gives
you a place to put hooks that will be called whenever the pointers are
dereferenced, e.g. for locking, or even just profiling: "How many times
are foo instances accessed? What is the duration of each access?"
> I really don't see any purpose for NULL, 0, or nullptr.
Before somebody goes flame-crazy, let me correct myself: There are
valid uses of the integer-literal 0. It's just inferior to a null
pointer of a specific static type.
I suppose some people prefer to clearly see from the code that a
pointer is really a pointer. If you have something like:
PFoo x = someFunction();
then it's not at all clear whether the function is returning a pointer
to something, or a value.
In C++ pointers vs. values play a much more important role than in
many other languages, where the difference is less relevant (if not even
completely hidden by syntax). In C++ you often need to be careful where
your pointers are pointing to (in order to avoid, among other things,
dangling pointers), so pointers in particular require extra care when
programming. Thus clearly seeing that something is a pointer can only
help in this task. Hiding a pointer behind a typedef can only make the
task harder.
Once you learn the syntax throughly, this merely incurs an extra level
of indirection for a struct/class/union in C++ (without actually
making it more convenient to compile anything).
The syntax for function pointers (and function references) is not as
easy to casually improvise. My current bias is to use typedefs for
function pointers and function references.
(Unfortunately, I don't know how to construct a function reference
typedef manually. The usual technique for faking a template typedef
does allow defining the function reference typedef.)
It's bad style, in C and C++.
You better define your pointer types as you do here:
typedef Foo* PFoo;
and use them, because:
Foo* a,b;
is not the same as:
PFoo a,b;
at all.
That said, I prefer to use a postfix P: FooP or even FooPtr.
In some case, when I define a more abstract API, I would define:
typedef struct { ... } FooS;
typedef FooS* Foo;
and let the users of Foo be oblivious of the fact that it's a pointer.
--
__Pascal Bourguignon__
Ok, so you find an advantage in writing
typedef Foo* PFoo;
PFoo a, b;
while I would just write
Foo* a;
Foo* b;
I have to waste a whole 12 characters in my declarations, while you
use an additional 16 characters in the typedef, so you can get down to
just 8 in the declarations. Let's see now, how much typing did you
save?
(me 12, you 24)
Bo Persson
Hm, I could save a lot of characters if instead of
const int number_of_runs = 18;
...
for ( int n = 0; n < number_of_runs; ++n ) {
...
}
I would do
...
for ( int n = 0; n < 18; ++n ) {
...
}
But for some reason, I don't like magic numbers.
Actually, I don't like magic types either; and I think the reason is more or
less the same.
Best
Kai-Uwe Bux
2 and 3 above are about cases where the typedef performs some kind of
abstraction or change-insulation, much like a named integral constant does
for magic values. The original poster was talking about writing such a
typedef for EVERY user-defined type, such that one couldn't change the
typedef without breaking code. Even ignoring the pure redundancy of them,
there's no way to provide all the typedefs a user might need; in many
cases you'd need at least T*, T const*, T&, and T const&. If you didn't
provide these, the user would have an inconsistent mix of PFoo and Foo
const*, depending on whether the type he wanted was one covered by the set
of typedefs.
There is in a philosophically interesting case against pointer typedefs, namely
that at least at Microsoft a number of programmers don't *understand* them, and
so they write silly things like (I've added obfuscating prefixes because they
usually do)
typedef CFoo* PCFOO; // Or something, I don't care to remember.
...
void Foo( const PCFOO pcFoo ) { ... }
instead of
void foo( Foo const& foo )
That they really mean the latter is usually clear from the rest of the code.
And I think that's philosophically interesting because it raises the question:
is it a good idea to *really dumb down* code because maintainers are likely
incompetent and unable to understand more than the very simplest constructs?
I've done that dumbing down many a time. In one case where I didn't (not at
Microsoft, but a firm with even worse filthy development habits, of course ISO
certified...), I mean it's not at all easy to keep in mind all the time, just as
it's not easy to always use simple words and sentences of less than eight or ten
words, I got a lot of badmouthing because in the boss' opinion I'd written too
"ingenious" code (defining an operator instead of a C-like function) that "our
best programmers don't understand". Heh.
Cheers,
- Alf
> * blargg:
>> Jeff Schwab wrote:
>>> Bo Persson wrote:
>>>> Jeff Schwab wrote:
Protégeons la veuve et l'orphelin, but we'll still need a way to grow
knights.
I wonder what the knights attitute was with respect to the wimps,
thought...
--
__Pascal Bourguignon__
>
> Protégeons la veuve et l'orphelin, but we'll still need a way to grow
> knights.
>
> I wonder what the knights attitute was with respect to the wimps,
> thought...
>
Quite the amusing picture in my mind. Of course, once a knight was done
with his work, the result of his work doesn't usually move again. Whereas,
when a programmer is done with his work, someone generally gets to maintain
it. So... There is at least a little validity to staying within the bounds
of the mindpool of the company. Of course, there is a line where it is
better to educate than to dumb down.
joe
One rational reason is that you would need *two* typedefs, or give up
const:
struct Foo .......;
typedef Foo* PFoo;
typedef const Foo* PCFoo;
I see typedefed pointers very rarely, and I would not be happy if I
found one. Being a pointer type is a very special thing, and I almost
always want to see that directly in the type. (You obviously want that
too, because you replace * with a P).
/Jorgen
PS. Since you don't mention doing this for references, I suspect you
place too much emphasis on pointers. They are used a lot, but not
nearly as much as in C.
--
// Jorgen Grahn <grahn@ Ph'nglui mglw'nafh Cthulhu
\X/ snipabacken.se> R'lyeh wgah'nagl fhtagn!