0
#include <bitset>
#include <assert.h>
#include <stdio.h>
using namespace std;


int main()
{
    bitset<128> bs(42);
    bs[11]=0;
    bs[12]=1;
    assert(bs[12]==1);
    printf("bs[11]=%d\n", bs[11]);
    printf("bs[12]=%d\n", bs[12]);
    return 0;
}

console output: enter image description here

Why can't I simply get 0 or 1 as output ?

Ludovic Aubert
  • 9,534
  • 4
  • 16
  • 28
  • 4
    `%d` is for `int`s, whereas `bitset::operator[]` returns a `bitset::reference`. You can use `std::cout` (which is anyway a more modern c++ mechanism) to print a bitset element. – wohlstad Oct 03 '22 at 12:58
  • ps. If you paste your code here: https://cpp.sh/ you'll see the related warnings. – JohnLBevan Oct 03 '22 at 13:01
  • 2
    Turn up the compiler warnings. https://godbolt.org/z/j7qMMj1cG You can add `!= 0` or a cast to do what you're looking for. – Retired Ninja Oct 03 '22 at 13:01
  • 1
    Clang returns a compiler error - you can't pass a bitset::reference into a variadic function. – Spencer Oct 03 '22 at 13:01
  • Compiler finds the problem when warnings are enabled: https://godbolt.org/z/W37Ef5hWG – Marek R Oct 03 '22 at 13:07

3 Answers3

3

printf with %d is for integer values, whereas std::bitset::operator[] returns a std::bitset::reference.

You can use std::cout from <iostream> header (which is anyway a more c++ "way" to print to the console):

#include <bitset>
#include <assert.h>
#include <iostream>

int main()
{
    std::bitset<128> bs(42);
    bs[11] = 0;
    bs[12] = 1;
    assert(bs[12] == 1);
    std::cout << "bs[11]=" << bs[11] << std::endl;
    std::cout << "bs[12]=" << bs[12] << std::endl;
    return 0;
}

Output:

bs[11]=0
bs[12]=1

A side note: better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.

wohlstad
  • 12,661
  • 10
  • 26
  • 39
  • Ok, but this answer doesn't explain why the overload of `std::bitset::operator[]` returning a `bool` isn't [chosen](https://godbolt.org/z/1sEbvavKv), though. – Bob__ Oct 03 '22 at 13:42
  • @Bob__ interesting point. I am actually not sure. Perhaps you care to explain? In any case I believe my answer solves the OP's issue (plus steer them in the right direction of using iostream instead of printf). – wohlstad Oct 03 '22 at 15:42
  • 1
    I guess it depends on `std::printf` accepting a variadic list of *non* const parameters vs [`std::cout::operator<<`](https://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt) having an overload accepting a `bool`. I'm *not* a language lawyer, so please don't trust me. – Bob__ Oct 03 '22 at 15:51
2

If you are using C++ then don't call printf to output something (my compiler refuse to compile your code correctly). This C++ code works correctly using iostream:

#include <bitset>
#include <iostream> 

int main()
{
    std::bitset<128> bs(42);
    bs[11]=0;
    bs[12]=1;
    std::cout << "bs[11]=" << bs[11] << std::endl;
    std::cout << "bs[12]=" << bs[12] << std::endl;
    return 0;
}
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
2

With some review comments :

#include <cassert>
#include <bitset>
#include <iostream>

// anything with a .h extension is probably "C" not "C++"
// #include <assert.h>
//#include <stdio.h>
// using namespace std; <== NO, don't use using namespace std;

int main()
{
    std::bitset<128> bs(42);
    bs[11]=0;
    bs[12]=1;

    assert(bs[12]==1);

    std::cout <<"bs[11]" << bs[11] << "\n";
    std::cout << "bs[12]" << bs[11] << "\n";

    return 0;
}
Pepijn Kramer
  • 9,356
  • 2
  • 8
  • 19