-3

So here I have a part of my code where I define macros to set the identifier MIN_BIT to a value based on user input:

#define MIN_BITS(n) 1*n
int MIN_BIT = MIN_BITS(n);

And then I take user input for the value of 'n' in the main function.

Now, I have a function to take LSB, arrange it in an array, and print the array in reverse order so MSB is on the left:

void print_binary( unsigned number )
{
    unsigned bits [ MIN_BIT ] ; // <-- error here
    int count = 0 ;
    while( number>0 || count < MIN_BIT )
    {
        bits [count] = number % 2;
        number >>= 1;
        count++;
    }
    for( int i = count -1; i >=0; i--)
        cout << bits[i];
}

However, on the line marked 1 in the above code, I get an error "expression must have a constant value". The value of variable MIN_BIT cannot be used as a constant.

Please suggest a workaround for the issue, or a way to implement this differently.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Chris
  • 11
  • 7
  • C++ does not make lazy evaluation by default. Once `MIN_BIT` is created, its value won't change when you change the value of `n`. – YSC Sep 14 '17 at 15:48
  • yikes!! theres quite a lot that needs changing here – AngryDuck Sep 14 '17 at 15:49
  • 2
    Then, the error you get is self-explanatory. If you need a contiguous array whose size depends on a runtime value, use `std::vector`. – YSC Sep 14 '17 at 15:49
  • Please be aware of the difference between a constant, and a compile-time constant. A compile-time constant is a constant whos value is known at compile-time, by definition before any user input can be received. In this context, `MIN_BIT` would need to be a compile-time constant. In most cases, use [`std::vector`](http://en.cppreference.com/w/cpp/container/vector) if you need a container who's size is only known at run time. – François Andrieux Sep 14 '17 at 15:55
  • @AngryDuck Oops, sorry that the code wasn't properly inundated..:( – Chris Sep 14 '17 at 16:03
  • @YSC Well I'm a noob so would love it if u show me how to implement it – Chris Sep 14 '17 at 16:05
  • @FrançoisAndrieux Quite informative..:) – Chris Sep 14 '17 at 16:12
  • @FrançoisAndrieux could u please show me an example? – Chris Sep 14 '17 at 16:24

1 Answers1

1

Try this instead:

#define MIN_BITS(t) (sizeof(t) * 8)

Or, use CHAR_BIT if you need to support systems where a byte is not 8 bits in size:

#define MIN_BITS(t) (sizeof(t) * CHAR_BIT)

Then, you can do this:

void print_binary( unsigned number )
{
    const int num_bits = MIN_BITS(number);

    unsigned bits [ num_bits ];
    int count;

    for(count = 0; (number != 0) && (count < num_bits); ++count)
    {
        bits[count] = number & 1;
        number >>= 1;
    }

    for(int i = count-1; i >= 0; --i)
        cout << bits[i];
}

Live demo


You can't define a static fixed-length array using a value determined at runtime (that is known as a Variable Length Array, which is non-standard and only a few compilers implement it as an extra feature). If you need that, use std::vector instead:

#include <vector>

void print_binary( unsigned number )
{
    std::vector<unsigned> bits;
    bits.reserve(n);

    for(int i = 0; (number != 0) && (i < n); ++i)
    {
        bits.push_back(number & 1);
        number >>= 1;
    }

    for(int i = bits.size()-1; i >= 0; --i)
        cout << bits[i];
}

Otherwise, just define the array to be as large as the maximum bits that the input variable can physically hold, and then use the user entered value to limit how many values you can store in the array:

#define MAX_BITS(t) (sizeof(t) * CHAR_BIT)

void print_binary( unsigned number )
{
    const int max_bits = MAX_BITS(number);

    unsigned bits [ max_bits ];
    int count;

    for(count = 0; (number != 0) && (count < n) && (count < max_bits); ++count)
    {
        bits[count] = number & 1;
        number >>= 1;
    }

    for(int i = count-1; i >= 0; --i)
        cout << bits[i];
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • What If I need to set MIN_BITS(t) as 2, 3, 4, 5 bits and so on? – Chris Sep 14 '17 at 16:43
  • @chrisstone why would you need to do that? You have an input value of a given type, you should output as many bits as it physically has (or, at least as many bits needed to represent the numeric value). If you want fewer bits, use a smaller data type. It doesn't make sense to let the user enter the bit count, especially since your original code wasn't doing proper bounds checking and could overflow the array if the numeric value was larger than the bits requested (because you used `||` instead of `&&` in your `while` loop). What is your use case for letting the user enter the bit count? – Remy Lebeau Sep 14 '17 at 16:53
  • With the help MIN_BIT(t) I'm actually going to calculate the number of variables defining a Boolean function, for example if a Boolean expression is defined by three variables a,b and c the user would enter '3' as input. Even if I would use char datatype for the input variables I would get 8*8=16 bits whereas I require MIN_BITS to be '3' – Chris Sep 14 '17 at 16:54
  • That makes absolutely no sense in the context of the code you showed. You can't define a static fixed-length array using a value determined at runtime (that is known as a Variable Length Array, which is non-standard and only a few compilers implement it as an extra). If you need that, use `std::vector` instead. Otherwise, define the array to be as large as the max bits the input variable can physically hold, and then use the user entered value to limit how many values you can store in the array. – Remy Lebeau Sep 14 '17 at 17:00
  • Thank you so much Remy, setting MAX_BIT to a fixed value and reading value of MIN_BIT from user really helped. Although I'm really sorry for being a noob and not making things clear at the beginining. I will Google around to see the implementation of std: : vector now. Just a side note I use VS2017 as my compiler for the purpose..:) – Chris Sep 14 '17 at 18:31