Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #12718 > unrolled thread

Confused about casts

Started byPaulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt>
First post2011-12-21 01:54 +0000
Last post2011-12-21 19:45 +0000
Articles 8 — 3 participants

Back to article view | Back to comp.lang.c++


Contents

  Confused about casts Paulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt> - 2011-12-21 01:54 +0000
    Re: Confused about casts "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-12-21 03:28 +0100
      Re: Confused about casts Paulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt> - 2011-12-21 18:56 +0000
        Re: Confused about casts Leigh Johnston <leigh@i42.co.uk> - 2011-12-21 19:10 +0000
        Re: Confused about casts "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2011-12-21 20:32 +0100
      Re: Confused about casts Paulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt> - 2011-12-21 19:32 +0000
      Re: Confused about casts Paulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt> - 2011-12-21 19:34 +0000
    Re: Confused about casts (sorry) Paulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt> - 2011-12-21 19:45 +0000

#12718 — Confused about casts

FromPaulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt>
Date2011-12-21 01:54 +0000
SubjectConfused about casts
Message-ID<jcre8g$ecq$1@speranza.aioe.org>
Hi,
Pls. consider the following code:

using namespace std;

#include <iostream>
#include <fstream>

int main(int argc,char **argv)
{	ifstream *in_p;
	int val;
	if (argc==2)
	{	in_p=new ifstream(argv[1]);
		// Test in_p->good()
	}
	else
		in_p=static_cast<ifstream*>(&cin);
	*in_p >> val;
	cout << "val=" << val << endl;
	if (in_p!=&cin)
		delete in_p;
	return 0;
}

In the line "in_p=static_cast<ifstream*>(&cin);" both static and
reinterpret casts seem to work. Which is (more) correct?

Thanks.

[toc] | [next] | [standalone]


#12719

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2011-12-21 03:28 +0100
Message-ID<jcrg8s$2o8$1@dont-email.me>
In reply to#12718
On 21.12.2011 02:54, Paulo da Silva wrote:
>
> using namespace std;
>
> #include<iostream>
> #include<fstream>
>
> int main(int argc,char **argv)
> {	ifstream *in_p;
> 	int val;
> 	if (argc==2)
> 	{	in_p=new ifstream(argv[1]);
> 		// Test in_p->good()
> 	}
> 	else
> 		in_p=static_cast<ifstream*>(&cin);
> 	*in_p>>  val;
> 	cout<<  "val="<<  val<<  endl;
> 	if (in_p!=&cin)
> 		delete in_p;
> 	return 0;
> }
>
> In the line "in_p=static_cast<ifstream*>(&cin);" both static and
> reinterpret casts seem to work. Which is (more) correct?

They are both technically allowed, and both are *wrong*.

static_cast is allowed because ifstream is derived from istream so that 
the opposite direction would convert implicitly.

reinterpret_cast is allowed because just about any data pointers can be 
reinterpret_cast'ed, although for cases outside the conversions listed 
here and there in the standard the result (and whether it's allowed) 
depends on the compiler and compiler options.

You're doing a so called *downcast*, to a more derived class.

That's only proper if the referred to object is of the derived class (or 
more derived).

Here's what you should do, given the apparent goals of your code:


<code>
using namespace std;

#include <iostream>
#include <fstream>

void do_things( istream& in )
{
     int val;

     in >> val;
     cout << "val=" << val << endl;
}

int main( int argc,char *argv[] )
{	
     if (argc==2)
     {
         ifstream f( argv[1] );
         // Test in_p->good()
         do_things( f );
     }
     else
     {
         do_things( cin );
     }
}
</code>


Disclaimer: code untouched by compiler's dirty hands.


Cheers & hth.,

- Alf

PS: I liked your placing "using namespace std;" at the very top. I'll 
start doing that. It's never to late to pick up a good idea! :-)

[toc] | [prev] | [next] | [standalone]


#12732

FromPaulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt>
Date2011-12-21 18:56 +0000
Message-ID<jcta4v$kfn$1@speranza.aioe.org>
In reply to#12719
Em 21-12-2011 02:28, Alf P. Steinbach escreveu:
> On 21.12.2011 02:54, Paulo da Silva wrote:
>>
>> using namespace std;
>>
>> #include<iostream>
>> #include<fstream>
>>
>> int main(int argc,char **argv)
>> {    ifstream *in_p;
>>     int val;
>>     if (argc==2)
>>     {    in_p=new ifstream(argv[1]);
>>         // Test in_p->good()
>>     }
>>     else
>>         in_p=static_cast<ifstream*>(&cin);
>>     *in_p>>  val;
>>     cout<<  "val="<<  val<<  endl;
>>     if (in_p!=&cin)
>>         delete in_p;
>>     return 0;
>> }
>>
>> In the line "in_p=static_cast<ifstream*>(&cin);" both static and
>> reinterpret casts seem to work. Which is (more) correct?
> 
> They are both technically allowed, and both are *wrong*.
> 
> static_cast is allowed because ifstream is derived from istream so that
> the opposite direction would convert implicitly.
> 
> reinterpret_cast is allowed because just about any data pointers can be
> reinterpret_cast'ed, although for cases outside the conversions listed
> here and there in the standard the result (and whether it's allowed)
> depends on the compiler and compiler options.
> 
> You're doing a so called *downcast*, to a more derived class.
> 
> That's only proper if the referred to object is of the derived class (or
> more derived).
> 
> Here's what you should do, given the apparent goals of your code:
> 
> 
> <code>
> using namespace std;
> 
> #include <iostream>
> #include <fstream>
> 
> void do_things( istream& in )
> {
>     int val;
> 
>     in >> val;
>     cout << "val=" << val << endl;
> }
> 
> int main( int argc,char *argv[] )
> {   
>     if (argc==2)
>     {
>         ifstream f( argv[1] );
>         // Test in_p->good()
>         do_things( f );
>     }
>     else
>     {
>         do_things( cin );
>     }
> }
> </code>
Thanks!
But using the same logic, may be a little change fixes the problem.
Isn't this the same?

<code>
using namespace std;

#include <iostream>
#include <fstream>

int main(int argc,char **argv)
{	istream *in_p;
	int val;
	if (argc==2)
	{	in_p=new ifstream(argv[1]);
		// Test in_p->good()
	}
	else
		in_p=&cin;
	*in_p >> val;
	cout << "val=" << val << endl;
	if (in_p!=&cin)
		delete in_p;
	return 0;
}
</code>



> 
> 
> Disclaimer: code untouched by compiler's dirty hands.
> 
> 
> Cheers & hth.,
> 
> - Alf
> 
> PS: I liked your placing "using namespace std;" at the very top. I'll
> start doing that. It's never to late to pick up a good idea! :-)

Yes :-) For small/medium projects no need for namespaces.
Thank you

[toc] | [prev] | [next] | [standalone]


#12733

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-12-21 19:10 +0000
Message-ID<sbudnQL9gpOssm_TnZ2dnUVZ8s-dnZ2d@giganews.com>
In reply to#12732
On 21/12/2011 18:56, Paulo da Silva wrote:
> Em 21-12-2011 02:28, Alf P. Steinbach escreveu:
>> On 21.12.2011 02:54, Paulo da Silva wrote:
>>
>> PS: I liked your placing "using namespace std;" at the very top. I'll
>> start doing that. It's never to late to pick up a good idea! :-)
>
> Yes :-) For small/medium projects no need for namespaces.
> Thank you

Yes for toy programs or example code 'using namespace std;' at namespace 
scope is certainly quite common but it is a bad habit and should be 
avoided for any serious code; in your example that would mean using 
std::cout and std::istream instead.

HTH.

/Leigh

[toc] | [prev] | [next] | [standalone]


#12735

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2011-12-21 20:32 +0100
Message-ID<jctc93$q2e$1@dont-email.me>
In reply to#12732
On 21.12.2011 19:56, Paulo da Silva wrote:
> Em 21-12-2011 02:28, Alf P. Steinbach escreveu:
>> On 21.12.2011 02:54, Paulo da Silva wrote:
>>>
>>> using namespace std;
>>>
>>> #include<iostream>
>>> #include<fstream>
>>>
>>> int main(int argc,char **argv)
>>> {    ifstream *in_p;
>>>      int val;
>>>      if (argc==2)
>>>      {    in_p=new ifstream(argv[1]);
>>>          // Test in_p->good()
>>>      }
>>>      else
>>>          in_p=static_cast<ifstream*>(&cin);
>>>      *in_p>>   val;
>>>      cout<<   "val="<<   val<<   endl;
>>>      if (in_p!=&cin)
>>>          delete in_p;
>>>      return 0;
>>> }
>>>
>>> In the line "in_p=static_cast<ifstream*>(&cin);" both static and
>>> reinterpret casts seem to work. Which is (more) correct?
>>
>> They are both technically allowed, and both are *wrong*.
>>
>> static_cast is allowed because ifstream is derived from istream so that
>> the opposite direction would convert implicitly.
>>
>> reinterpret_cast is allowed because just about any data pointers can be
>> reinterpret_cast'ed, although for cases outside the conversions listed
>> here and there in the standard the result (and whether it's allowed)
>> depends on the compiler and compiler options.
>>
>> You're doing a so called *downcast*, to a more derived class.
>>
>> That's only proper if the referred to object is of the derived class (or
>> more derived).
>>
>> Here's what you should do, given the apparent goals of your code:
>>
>>
>> <code>
>> using namespace std;
>>
>> #include<iostream>
>> #include<fstream>
>>
>> void do_things( istream&  in )
>> {
>>      int val;
>>
>>      in>>  val;
>>      cout<<  "val="<<  val<<  endl;
>> }
>>
>> int main( int argc,char *argv[] )
>> {
>>      if (argc==2)
>>      {
>>          ifstream f( argv[1] );
>>          // Test in_p->good()
>>          do_things( f );
>>      }
>>      else
>>      {
>>          do_things( cin );
>>      }
>> }
>> </code>
> Thanks!
> But using the same logic, may be a little change fixes the problem.
> Isn't this the same?
>
> <code>
> using namespace std;
>
> #include<iostream>
> #include<fstream>
>
> int main(int argc,char **argv)
> {	istream *in_p;
> 	int val;
> 	if (argc==2)
> 	{	in_p=new ifstream(argv[1]);
> 		// Test in_p->good()
> 	}
> 	else
> 		in_p=&cin;
> 	*in_p>>  val;
> 	cout<<  "val="<<  val<<  endl;
> 	if (in_p!=&cin)
> 		delete in_p;
> 	return 0;
> }
> </code>


Well, it's not quite the same:

   * It uses dynamic allocation, which is generally slow.

   * It's in general not exception safe.

   * At least to my eyes, it's much less clear.

The problem is that this code addresses many concerns within the same 
little stretch of code.

Instead, try to separate concerns.


Cheers & hth.

- Alf

[toc] | [prev] | [next] | [standalone]


#12736

FromPaulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt>
Date2011-12-21 19:32 +0000
Message-ID<jctc8d$phn$1@speranza.aioe.org>
In reply to#12719
Em 21-12-2011 02:28, Alf P. Steinbach escreveu:
> On 21.12.2011 02:54, Paulo da Silva wrote:
>>
>> using namespace std;
>>
>> #include<iostream>
>> #include<fstream>
>>
>> int main(int argc,char **argv)
>> {    ifstream *in_p;
>>     int val;
>>     if (argc==2)
>>     {    in_p=new ifstream(argv[1]);
>>         // Test in_p->good()
>>     }
>>     else
>>         in_p=static_cast<ifstream*>(&cin);
>>     *in_p>>  val;
>>     cout<<  "val="<<  val<<  endl;
>>     if (in_p!=&cin)
>>         delete in_p;
>>     return 0;
>> }
>>
>> In the line "in_p=static_cast<ifstream*>(&cin);" both static and
>> reinterpret casts seem to work. Which is (more) correct?
> 
> They are both technically allowed, and both are *wrong*.
> 
> static_cast is allowed because ifstream is derived from istream so that
> the opposite direction would convert implicitly.
> 
> reinterpret_cast is allowed because just about any data pointers can be
> reinterpret_cast'ed, although for cases outside the conversions listed
> here and there in the standard the result (and whether it's allowed)
> depends on the compiler and compiler options.
> 
> You're doing a so called *downcast*, to a more derived class.
> 
> That's only proper if the referred to object is of the derived class (or
> more derived).
> 
> Here's what you should do, given the apparent goals of your code:
> 
> 
> <code>
> using namespace std;
> 
> #include <iostream>
> #include <fstream>
> 
> void do_things( istream& in )
> {
>     int val;
> 
>     in >> val;
>     cout << "val=" << val << endl;
> }
> 
> int main( int argc,char *argv[] )
> {   
>     if (argc==2)
>     {
>         ifstream f( argv[1] );
>         // Test in_p->good()
>         do_things( f );
>     }
>     else
>     {
>         do_things( cin );
>     }
> }
> </code>
Thanks!
But using the same logic, may be a little change fixes the problem.
Isn't this the same?

<code>
using namespace std;

#include <iostream>
#include <fstream>

int main(int argc,char **argv)
{	istream *in_p;
	int val;
	if (argc==2)
	{	in_p=new ifstream(argv[1]);
		// Test in_p->good()
	}
	else
		in_p=&cin;
	*in_p >> val;
	cout << "val=" << val << endl;
	if (in_p!=&cin)
		delete in_p;
	return 0;
}
</code>



> 
> 
> Disclaimer: code untouched by compiler's dirty hands.
> 
> 
> Cheers & hth.,
> 
> - Alf
> 
> PS: I liked your placing "using namespace std;" at the very top. I'll
> start doing that. It's never to late to pick up a good idea! :-)

Yes :-) For small/medium projects no need for namespaces.
Thank you

[toc] | [prev] | [next] | [standalone]


#12737

FromPaulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt>
Date2011-12-21 19:34 +0000
Message-ID<jctccn$pss$1@speranza.aioe.org>
In reply to#12719
Em 21-12-2011 02:28, Alf P. Steinbach escreveu:
...

> 
> Here's what you should do, given the apparent goals of your code:
> 
> 
> <code>
> using namespace std;
> 
> #include <iostream>
> #include <fstream>
> 
> void do_things( istream& in )
> {
>     int val;
> 
>     in >> val;
>     cout << "val=" << val << endl;
> }
> 
> int main( int argc,char *argv[] )
> {   
>     if (argc==2)
>     {
>         ifstream f( argv[1] );
>         // Test in_p->good()
>         do_things( f );
>     }
>     else
>     {
>         do_things( cin );
>     }
> }
> </code>
Thanks!
But using the same logic, may be a little change fixes the problem.
Isn't this the same?

<code>
using namespace std;

#include <iostream>
#include <fstream>

int main(int argc,char **argv)
{	istream *in_p;
	int val;
	if (argc==2)
	{	in_p=new ifstream(argv[1]);
		// Test in_p->good()
	}
	else
		in_p=&cin;
	*in_p >> val;
	cout << "val=" << val << endl;
	if (in_p!=&cin)
		delete in_p;
	return 0;
}
</code>

> 
> 
> Disclaimer: code untouched by compiler's dirty hands.
> 
> 
> Cheers & hth.,
> 
> - Alf
> 
> PS: I liked your placing "using namespace std;" at the very top. I'll
> start doing that. It's never to late to pick up a good idea! :-)

Yes :-) For small/medium projects no need for namespaces.
Thank you

[toc] | [prev] | [next] | [standalone]


#12738 — Re: Confused about casts (sorry)

FromPaulo da Silva <p_s_d_a_s_i_l_v_a@netcabo.pt>
Date2011-12-21 19:45 +0000
SubjectRe: Confused about casts (sorry)
Message-ID<jctd17$r2s$1@speranza.aioe.org>
In reply to#12718
Sorry for the multi posts!!!
But my News client was informing me that it could not send the posts
while it was really sending them.

Thank you

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web