Jump to content
Martin Barnasconi

missing proxy to automatically cast an sc_bv element to a bool?

Recommended Posts

Hi all,

 

I'm using a bit-select of a sc_bv in an expression, something like this:

 

sc_bv<8> mybits;
...
if (mybits[0].to_bool())
  // do something

 

Sure this works, but I'm not so happy with this coding style. Therefore I expected some intelligence in the sc_proxy class to resolve the bit to bool conversion, simply because the sc_bv can be seen as an array of bools.

 

I expected that this would work as well:

sc_bv<8> mybits;
...
if (mybits[0]) // compiler error here
  // do something

 

Pity... we get the following compiler error:

 

... error: could not convert ‘sc_dt::sc_proxy<X>::operator[](int) [with X = sc_dt::sc_bv_base](0)’ to ‘bool’

It seems this type of functionality is not (or cannot be) implemented in the sc_proxy?

 

Share this post


Link to post
Share on other sites

A number of us have noticed this problem. It appears that as

sc_dt::sc_bv<n> is basically a container for sc_dt::sc_bit

data type, the direct conversion to the plain C++ data type

'bool' is not straightforward. In some of my more complicated

designs, a brute force manual conversion is used, as

if(my_bv[0] == "0") boolA = false;

where boolA is of type bool.

As for why the proxy does not work, it is not clear.

Share this post


Link to post
Share on other sites

Hi Martin,

 I think the reason is that you can get to bool from the sc_bit_ref class via sc_lv or sc_bv, so it is ambiguous. You get the same problem when using range() and concat() methods.

 

Another way to make it unambiguous would be to cast the result of the bit_ref to either sc_lv<1> or sc_bv<1>, because then the user defined type conversion to bool should be  unambiguous.

 

E.g.

 

 

 if ( sc_bv<1>(my_bits[0]) ) 

 

or

 

  if (sc_lv<1>(my_bits[0]))

 

 

I haven't tried that, but I think it should work.

For maximum code obscurity  :)  why not try

 

 

if ( static_cast<sc_lv<1> >(my_bits[0]) ) 

 

 

 

regards

Alan

Share this post


Link to post
Share on other sites

Hello Alan,

 

I tried your 3 suggestions, but none of them work. And that is good, because the modeling style was getting even more ugly than using the to_bool() method ;)

 

My initial compiler error shows that it recognizes the input as an object derived from sc_dt::sc_bv_base. In a similar way, a sc_lv will be identified as derived from sc_dt::sc_lv_base. Therefore I think this automatic casting to bool is simply a missing functionality in the sc_proxy.

 

But as the sc_proxy as such is not a documented feature in the LRM, I cannot officially complain that something is missing ;)

Share this post


Link to post
Share on other sites

Ah OK - I know that style works with converting ranges to integers, e.g. you can cast the range of an sc_lv to an sc_lv, and then operator= converts it to sc_int etc.

 

That'll teach me for posting code without testing it :-)

 

regards

Alan

Share this post


Link to post
Share on other sites

Sorry for the late reply, but let me try to shed some light on this.
 
Internally, the sc_bitref(_r) classes (which are returned by the operator[] of sc_proxy<X> and are (an implementation-defined) part of the standard) assume sc_logic as value type for both sc_bv and sc_lv.  This is the main reason, why using bit-selects in boolean contexts is not directly possible.
 
Adding an implicit conversion from sc_bitref_r and/or sc_logic to bool is not reasonable (and will likely cause ambiguities in existing models).  Still, I agree that this is inconvenient and unexpected especially in case of sc_bv bit-selects.  The best solution would be to update the bit-select (and range-select) definitions to inherit the value type from their underlying objects.  This would require some refactoring of these parts of the standard and careful analysis of resulting backwards-compatibility problems.
 
But since the internal conversions work fine is most cases, I would suggest to add a boolean conversion based on the safe bool idiom. The implementation would be fairly straight-forward (untested, to be added to sc_logic and sc_bitref_r):

 

class sc_logic // or sc_bitref_r
{
  typedef sc_logic this_type; // or sc_bitref_r
  typedef bool (this_type::*boolean_type)() const;
  // ...
public:
    operator boolean_type() const {
      return this->to_bool() ? &this_type::to_bool : 0;
    }
};

Of course, we still need to check for ambiguities or other unwanted side-effects.  But since the comparisons should already be explicitly defined, it Should Work™.

 

Greetings from Oldenburg,
  Philipp

Share this post


Link to post
Share on other sites

Minor addition: According to 1666-2011, Section 7.9.2.7, an explicit comparison with bool should work for bit-selects:

 

if( bv[0] == true )
  /* ... */ ;

 

This doesn't look too bad, does it?

 

HTH,

  Philipp

 

I feel bit happy that a SystemC guru has thought in a similar manner

as I did, when I made my original suggestion -- solutions must be simple,

precise and unambiguous. This solution solves the problem admirably,

completely bypassing the complexities of using casts. Using a cast is

in a way forcing the compiler to do something that it normally would not

do, and one has to be careful to watch out for side-effects.

.  

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×