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

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...