1

Having simple c++ program like so:

#include <stdio.h>
#include <limits.h>

template <typename T>
char BinVal(T SrcVal) {
    
    //short BitsCount = sizeof(T)*CHAR_BIT;
    short BitsCount = sizeof(T)*CHAR_BIT;
    short SeparatorCount = sizeof(T)*2-1;
    short SeparatorSize = CHAR_BIT/2+1;
    static char BinValStr[ BitsCount + SeparatorCount ] = {0};
  
    printf("BitsCount: %d\n", BitsCount);
    printf("SeparatorCount: %d\n", SeparatorCount);
    printf("BinValStr size: %d\n", BitsCount + SeparatorCount);
    
    int i = 0;
    int j = 0;
    
    for ( i=BitsCount+SeparatorCount-1; i>=0; i-- ) {

        if( (j+1)%SeparatorSize == 0) {
            BinValStr[i] = ' ';
        }
        else {
            if( SrcVal&1 == 1 )
                BinValStr[i] = '1';
            else
                BinValStr[i] = '0';
                SrcVal >>=1;
        }
        j++;
    
    }
    
    char y='o';
    return y;
    //return BinValStr;
    //printf("\nStr: %s", BinValStr);
}

int main(){
    
    short val = 0b0000'0100'0001'0110; //18 dec
    printf("\nStr: %c", BinVal(val) );
}

i get "storage size of ‘BinValStr’ isn’t constant" error.

When i make the BinValStr var "normal", local everything is OK. Why does making the variable static gives me the error?

4
  • 2
    Please provide a minimal reproducible example. What you have shown is not a simple c++ program. It does not compile. Commented Aug 10, 2020 at 6:13
  • Sorry, it can not be reproduced: godbolt.org/z/EocjEh Commented Aug 10, 2020 at 6:22
  • @Const you're running it in O3 mode without static checks.. template wasn't checked\instantiated Commented Aug 10, 2020 at 6:25
  • Ok here is the complete program Commented Aug 10, 2020 at 6:27

2 Answers 2

3

This is not an answer to your question, "Swift - Friday Pie" has already covered that. Instead I want to point out a small issue in some of your other code:

if( SrcVal&1 == 1 )

While this works, it may not work like you think. In short: == binds harder (has higher precedence) than &.

https://en.cppreference.com/w/cpp/language/operator_precedence

This means that the above if goes like this:

1 == 1 => true. SrcVal & true => SrcVal & 1 => does the bitwise AND and returns 1 or 0. That number is then interpreted as a truth value and gives the result you want. So why is it a problem when it works? Well, lets say that you want the same test again, but now you are looking for when the first bit of ScrVal is 0, so you write:

if( SrcVal&1 == 0 )

And now it just never works because: 1 == 0 => false. ScrVal & false => ScrVal & 0 => 0.

How to fix it? The two easy options:

  • Wrap the bitwise AND in parenthesis: if( (SrcVal & 1) == 1 )
  • Omit the comparison: if( SrcVal & 1 )
Sign up to request clarification or add additional context in comments.

1 Comment

I guess OP needs std::bitset instead of any array type.
2

You attempted to use varaibles as size of array, while you need compile-time values. ISO C++ doesn't allow to allocate array dynamically (GNU extension for variable length arrays is an exception), thus expression for size of array should be constexpr

template <typename T>
char BinVal(T SrcVal) { 
    constexpr short BitsCount = sizeof(T)*CHAR_BIT;
    constexpr short SeparatorCount = sizeof(T)*2-1;
    
    constexpr short SeparatorSize = CHAR_BIT/2+1;
    static char BinValStr[ BitsCount + SeparatorCount ] = {0};

Pre-C++11 variant could be just static const or using integral_constant or similar construct.

5 Comments

Also, <array>.
@DevSolar if allowed (and supported), yes, of course. It also a good learning experience to peek into implementation of those simple templates, std::array, integral_constant essentially do something like this inside.
While std::array probably is a better idea than []-array, not that it also requires its size to be a compile-time constant. So this answer applies there too.
Thx. guys for help, i suspected that the key is just making the variables const, but what's REALLY bizarre - when i remove static keyword form BinValStr definition (making it local) the code DO WORKS (no errors or warnings) even there is noconst medifier for the variables!???
@DarosRT10 you likely use GNU compiler then, or compatible. That's VLA, a C feature which isn't supported by C++ standard. Essentislly it's a dynamic array in stack with limitation that you cannot pass it out of function. VLA cannot be static or global. E.g. g++ supports it by default

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.