public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Can I avoid "shift count is negative" warning? (involves template parameter)
@ 2007-05-03 20:42 Phil Endecott
  2007-05-03 20:49 ` John Love-Jensen
  2007-05-03 21:26 ` jlh
  0 siblings, 2 replies; 5+ messages in thread
From: Phil Endecott @ 2007-05-03 20:42 UTC (permalink / raw)
  To: gcc-help

Dear Experts,

template <int a>
int shift (int b)
{
   return (a>0) ? b>>a : b<<-a;
}

int f()
{
   return shift<1>(1);
   return shift<-1>(1);
}


$ g++ -W -c shiftwarn.cc
shiftwarn.cc: In function ‘int shift(int) [with int a = 1]’:
shiftwarn.cc:11:   instantiated from here
shiftwarn.cc:5: warning: left shift count is negative
shiftwarn.cc: In function ‘int shift(int) [with int a = -0x00000000000000001]’:
shiftwarn.cc:12:   instantiated from here
shiftwarn.cc:5: warning: right shift count is negative



Of course, the shift count is only negative in the branch of the the ?: 
that isn't used.

I get the same warning if I use if-then-else rather than ?:.  If 'a' is 
a regular function parameter rather than a template parameter, or if it 
is a constant, I don't get any warnings.

Is there any way to avoid this?  Do you consider it a bug?

This is g++ 4.1.2.

Many thanks for any suggestions.

Phil.

p.s. I've just noticed that it doesn't warn about having two return statements...



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can I avoid "shift count is negative" warning? (involves  template parameter)
  2007-05-03 20:42 Can I avoid "shift count is negative" warning? (involves template parameter) Phil Endecott
@ 2007-05-03 20:49 ` John Love-Jensen
  2007-05-03 21:56   ` me22
  2007-05-03 21:26 ` jlh
  1 sibling, 1 reply; 5+ messages in thread
From: John Love-Jensen @ 2007-05-03 20:49 UTC (permalink / raw)
  To: Phil Endecott, MSX to GCC

Hi Phil,

You can avoid it by using specialization.

For a 32-bit int, that would be 32 positive, and 32 negative
specializations.

Maybe a bit much, but it'd work.

HTH,
--Eljay


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can I avoid "shift count is negative" warning? (involves template  parameter)
  2007-05-03 20:42 Can I avoid "shift count is negative" warning? (involves template parameter) Phil Endecott
  2007-05-03 20:49 ` John Love-Jensen
@ 2007-05-03 21:26 ` jlh
  2007-05-03 21:42   ` Phil Endecott
  1 sibling, 1 reply; 5+ messages in thread
From: jlh @ 2007-05-03 21:26 UTC (permalink / raw)
  To: Phil Endecott, gcc-help

Hello!

This might not apply to g++ 4.1.2, which is what you use, but I
don't have this version right here to test it.  It works fine for
gentoo's g++ 4.1.1 and produces no warnings:

template <int a>
int shift (int b)
{
	if (a > 0) {
		unsigned ua = a;
		return b >> ua;
	} else {
		unsigned ua = -a;
		return b << ua;
	}
}
template int shift<1>(int);
template int shift<-1>(int);

However, you will have to turn on optimization in order to get the
same efficient code than with your version (x86 here).

(I do get a warning for converting -1 to unsigned on g++ 3.4.6)

jlh

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can I avoid "shift count is negative" warning? (involves  template parameter)
  2007-05-03 21:26 ` jlh
@ 2007-05-03 21:42   ` Phil Endecott
  0 siblings, 0 replies; 5+ messages in thread
From: Phil Endecott @ 2007-05-03 21:42 UTC (permalink / raw)
  To: jlh; +Cc: gcc-help

jlh wrote:
> template <int a>
> int shift (int b)
> {
> 	if (a > 0) {
> 		unsigned ua = a;
> 		return b >> ua;
> 	} else {
> 		unsigned ua = -a;
> 		return b << ua;
> 	}
> }
> template int shift<1>(int);
> template int shift<-1>(int);


Thanks, that works!

Phil.




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Can I avoid "shift count is negative" warning? (involves template parameter)
  2007-05-03 20:49 ` John Love-Jensen
@ 2007-05-03 21:56   ` me22
  0 siblings, 0 replies; 5+ messages in thread
From: me22 @ 2007-05-03 21:56 UTC (permalink / raw)
  To: John Love-Jensen; +Cc: Phil Endecott, MSX to GCC

On 03/05/07, John Love-Jensen <eljay@adobe.com> wrote:
> Hi Phil,
>
> You can avoid it by using specialization.
>
> For a 32-bit int, that would be 32 positive, and 32 negative
> specializations.
>
> Maybe a bit much, but it'd work.
>
> HTH,
> --Eljay
>
I think something like this should work, without needing so many
specializations:

template <int a, bool n = a<0>
struct rshift_by;
template <int a>
struct rshift_by<a, true> {
    static int shift(int b) { return b << -a; }
}
template <int a>
struct rshift_by<a, false> {
    static int shift(int b) { return b >> a; }
}

template <int a>
int shift (int b)
{
  return rshift_by<a>::shift(b);
}

int f()
{
  return shift<1>(1);
  return shift<-1>(1);
}

It also avoids the if branch on the compile-time constant, though GCC
is quite good at optimizing those. (IIRC some other compilers (MSVC)
whine about it, though.)

~ Scott McMurray

P.S. I love how the template syntax gives a<0>, don't you?

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-05-03 21:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-03 20:42 Can I avoid "shift count is negative" warning? (involves template parameter) Phil Endecott
2007-05-03 20:49 ` John Love-Jensen
2007-05-03 21:56   ` me22
2007-05-03 21:26 ` jlh
2007-05-03 21:42   ` Phil Endecott

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).