C Board  

Go Back   C Board > General Programming Boards > C++ Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 10-05-2008, 01:54 AM   #16
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
Quote:
Originally Posted by phantomotap View Post
However, I think your point was probably: how do I prevent the silent conversion to 'const char *' from causing problems when used with the subtraction operator. The answer is the same for every operator associated with the intended conversion: provide the operator and either prevent successful compilation or crash with a well-formed error during execution.
That was kindof the point, wasn't it?
So, you have an example?
I'd love to see you thwart the happy little compiler.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 10-05-2008, 02:15 AM   #17
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
Quote:
Originally Posted by phantomotap
The best part of this is: you are both wrong. First, it isn't a counter. Second, even with the implicit conversion it would not compile for a conforming compiler. Subtracting two pointers yields an integer type and 'std::string' has no such constructor.
I do not see what "it isn't a counter" has to do with anything. Concerning the error: I ignored that part due to the disclaimer that only C++ Coding Standards incorporates corrections, but thinking about it further, it cuts both ways: suppose the constructor that creates a string with n characters was changed such that the null character was default. In that case, implicit conversion would allow Sutter's otherwise problematic original example to compile when the conversion function is provided.

Quote:
Originally Posted by phantomotap
However, I think your point was probably: how do I prevent the silent conversion to 'const char *' from causing problems when used with the subtraction operator.
Precisely, though more generally, "to block otherwise logically illegal, or just silly, operations", as you yourself have pointed out much earlier.

Quote:
Originally Posted by phantomotap
The answer is the same for every operator associated with the intended conversion: provide the operator and either prevent successful compilation or crash with a well-formed error during execution.
That is easier said than done. Providing a named conversion function, on the other hand, is as easily done as said, and avoids those problems associated with implicit conversions.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 10-05-2008, 02:16 AM   #18
Registered User
 
Join Date: Jan 2008
Posts: 575
Quote:
I'd love to see you thwart the happy little compiler.
O_o

Thwart the compiler?! Are you insane?! I'm suggesting you use the compiler. That's why it exists. What don't you get? You can literally use any method of static assertion or compiler firewall you desire.

As I've implied: I use a meta-function to do this for any or all of the operators applied to any number of types--actually limited to 64. The massive overhead would be pointless, but I'll offer a trivial and sloppy way to block an operator for a type you don't own without otherwise affecting the compiler output, messages or errors, from "correct" source. Enjoy.

Quote:
That is easier said than done.
No. It isn't. I have a series of meta-functions that you simply invoke. (That is, it is as easy done as typed.)

Soma

Code:
class blocker{public: blocker(){} private:blocker(const blocker &){} friend blocker operator - (const my_string &, const my_string &);};

blocker operator -
(
  const my_string & lhs,
  const my_string & rhs
)
{
  blocker return_value;
  return(return_value);
}

Last edited by phantomotap; 10-05-2008 at 02:19 AM.
phantomotap is offline   Reply With Quote
Old 10-05-2008, 02:20 AM   #19
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
Quote:
Originally Posted by phantomotap View Post
Thwart the compiler?! Are you insane?! I'm suggesting you use the compiler. That's why it exists. What don't you get? You can literally use any method of static assertion or compiler firewall you desire.
In my view, you are opening up evil conversion with the implicit type operator, but then you are blocking them... so you open them up to the compiler and then you block them for the compiler.
That, essentially means thwart the compiler in my book
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 10-05-2008, 02:24 AM   #20
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
Quote:
Originally Posted by phantomotap
No. It isn't. I have a series of meta-functions that you simply invoke.
You still have to determine what to invoke, and have to update your code if there are additions to the target type interface (for class types not under your control, at least), even if these would not normally affect your code.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 10-05-2008, 02:47 AM   #21
Registered User
 
Join Date: Jan 2008
Posts: 575
Quote:
In my view, you are opening up evil conversion with the implicit type operator, but then you are blocking them...
O_o

Yea... that would be silly, but I'm not blocking the conversion. I'm telling the compiler that certain constructs are invalid... I'm basically marking conversions in certain contexts as private.

Quote:
You still have to determine what to invoke, and have to update your code if there are additions to the target type interface (for class types not control your control, at least), even if these would not normally affect your code.
If your code would not be affected by such additions then, by definition, no source change would be needed regardless of the source written to prevent such constructs from compiling. (Edit: Actually, I may be giving to much credit here; it is possible to write source that depends upon the firewall for correct compilation, but it is very unlikely to happen by accident.) That said, if you desire that your source makes use of these additional facilities, you would have to change something, but that's always the case.

Soma

Last edited by phantomotap; 10-05-2008 at 02:49 AM.
phantomotap is offline   Reply With Quote
Old 10-05-2008, 02:53 AM   #22
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
Quote:
Originally Posted by phantomotap
I'm telling the compiler that certain constructs are invalid... I'm basically marking conversions in certain contexts as private.
Yes, it is like declaring copy constructors and copy assignment operators private in order to disable copying.

Quote:
Originally Posted by phantomotap
If your code would not be affected by such additions then, by definition, no source change would be needed regardless of the source written to prevent such constructs from compiling.
Ah, but what if the type you are designing is intended for use (or just might be used) by another programmer (or team, as the case may be), as would be the case for a library? Such a source code change would be needed in order to maintain the interface provided.

Quote:
Originally Posted by phantomotap
That said, if you desire that your source makes use of these additional facilities, you would have to change something, but that's always the case.
When you put it as "additional facilities", I tend to agree with the notion that this would be a viable alternative to a named conversion function, though I am not convinced that it is worth the effort when a named conversion function can be clearer and just shifts the burden on using sensible operations from other types to the user of the type you provide.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way

Last edited by laserlight; 10-05-2008 at 02:57 AM.
laserlight is offline   Reply With Quote
Old 10-05-2008, 04:17 AM   #23
Registered User
 
Join Date: Jan 2008
Posts: 575
Quote:
When you put it as "additional facilities", I tend to agree with the notion that this would be a viable alternative to a named conversion function, though I am not convinced that it is worth the effort when a named conversion function can be clearer and just shifts the burden on using sensible operations from other types to the user of the type you provide.
O_o

I think I've spotted a flaw in your understanding. In a perfect world the responsibility, or burden if you like, of disabling conversions for specific constructs belongs to the provider of a type. (You wouldn't, or shouldn't, in using my library, or any other, go into the headers to mark some method private even if it should have been marked private.) Even in our world of shambles, the responsibility belongs to a single type. (Granted, in this case I've offered that it can "fix" an existing provision that didn't account for unwanted implicit conversion by displacing this burden, but that's not really the point.) The relevant source, even without templates, need only be written to disallow problematic conversions for each implicitly converted type for any given class type with such implicit conversions. The 'blocking' type is a "no-op"; it is no more associated with the relevant type nor any more responsible than 'std::string' would be if someone provides 'std::string operator + (const std::vector<?> &, unsigned long)'.

Soma

PS. And not that it matters, but I'm a big fan of consistency. I teach people to use 'static_cast<?>' even with classes offering implicit conversion. (With an exception of 'operator void *' and 'operator bool' because stream using source seems "right" without it.)

Last edited by phantomotap; 10-05-2008 at 04:24 AM.
phantomotap is offline   Reply With Quote
Old 10-05-2008, 05:31 AM   #24
The larch
 
Join Date: May 2006
Posts: 3,082
It is interesting that you start by saying
Quote:
No. They should not be avoided. If you do the work to block otherwise logically illegal, or just silly, operations they can make code much cleaner. (Of course, misused they can make code uglier, but that doesn't say much as it applies to most features of C++.)
and you finish with this

Quote:
PS. And not that it matters, but I'm a big fan of consistency. I teach people to use 'static_cast<?>' even with classes offering implicit conversion. (With an exception of 'operator void *' and 'operator bool' because stream using source seems "right" without it.)
So you would prefer:
Code:
ofsteam fout(static_cast<const char*>(filename));
//over
ofstream fout(filename.c_str());
Does this apply only to string-like things? Many classes can return objects of various types from different methods, would you also make the classes castable into these types?

Code:
Character c;
//Rect r = c.bounding_rect();
Rect r = static_cast<Rect>(c);
__________________
I might be wrong.

Quote:
Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Quoted more than 1000 times (I hope).
anon is offline   Reply With Quote
Old 10-05-2008, 05:33 AM   #25
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
Quote:
Originally Posted by phantomotap
The relevant source, even without templates, need only be written to disallow problematic conversions for each implicitly converted type for any given class type with such implicit conversions.
I do not understand what you are trying to say in the sentence quoted above, so kindly explain and elaborate.

What I meant is that since a named conversion function forces the user of the type to explicitly request the conversion, any abuse of this conversion is the user's fault. With an implicit conversion function, any abuse of this conversion is both the user's fault and the type designer's (or implementor's) fault. The former is at fault for a mistake in using the type, and the latter is at fault for failing to disable the constructs that are not sensible.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Old 10-05-2008, 10:03 AM   #26
Registered User
 
Lawn Gnomusrex's Avatar
 
Join Date: Oct 2008
Location: Leading lawn gnomes on the path to world domination! ;o)
Posts: 13
Exclamation

Thank you for explaining
Code:
operator char*() {return ptr;}
I also see this set off a discussion that would have made my head explode if I tried to understand most of it.
I guess the point of this 'don't use automatic conversions'? I understood only the a = b - c issue, I don't know how widgets work, so I didn't understand it.

I've never touched any programming language before, so my total programming experience extends to about 5 months. ^^;

I'm reading "C++ without fear", if that indicates how new I am to all of this. So I don't really know how to make an explicit conversion function. I saw this in the "books" sections of cprogramming, so I'm reading those. I looked into other books, but I know so little I didn't know what to go with. So this is the first book I ended up getting.

I got the information I came for though, So thanks everyone! (And when I figure out how to write a function to take the place of operator char*(), I'll be sure to use it.)
Lawn Gnomusrex is offline   Reply With Quote
Old 10-05-2008, 10:05 AM   #27
Mysterious C++ User
 
Join Date: Oct 2007
Posts: 14,099
The idea is that you create a function such as:
const char* get();
In your class instead of the implicit conversion operator:
operator const char* ();
This will eliminate the chance for these headaches.
__________________
Using: Microsoft Windows™ 7 Professional (x64), Microsoft Visual Studio™ 2008 Team System
I dedicated my life to helping others. This is only a small sample of what they said:
"Thanks Elysia. You're a programming master! How the hell do you know every thing?"
Quoted... at least once.
Quote:
Originally Posted by cpjust
If C++ is 2 steps forward from C, then I'd say Java is 1 step forward and 2 steps back.
Elysia is offline   Reply With Quote
Old 10-05-2008, 10:33 AM   #28
Registered User
 
Lawn Gnomusrex's Avatar
 
Join Date: Oct 2008
Location: Leading lawn gnomes on the path to world domination! ;o)
Posts: 13
Ahhh! Thank you, Elysia! I didn't know if making something like this required more work or not.

I appreciate the help, everyone! Thanks!
Lawn Gnomusrex is offline   Reply With Quote
Old 10-05-2008, 01:59 PM   #29
Cat without Hat
 
CornedBee's Avatar
 
Join Date: Apr 2003
Posts: 8,439
Also, non-const char* is bad for encapsulation. Basically, by returning a non-const char*, you implicitly give clients of your class leave to do with your internal string data whatever they want - not a good idea when the char* really belongs to the string object.
__________________
All the buzzt!
CornedBee

"There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
- Flon's Law
CornedBee is offline   Reply With Quote
Reply

Tags
class, classes, pointers, references, strings

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Can anybody show me why this works?? tzuch C Programming 2 03-29-2008 09:03 AM
Understanding formulas, shapes, algorithms etc hardi General Discussions 26 04-16-2007 01:23 PM
Works outside of the loop, not within Decrypt C++ Programming 5 08-05-2006 12:22 AM
understanding recursive functions houler C Programming 7 12-09-2004 12:56 PM
Understanding Headers and Inclusions jdm C++ Programming 11 04-21-2004 10:11 PM


All times are GMT -6. The time now is 11:04 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22