1

I have a bunch of bitsets<32> as global variables in my program and I want to update them after passing a pointer to one of them to a function.

Here is an example:

#include<bits/stdc++.h>
using namespace std; 
bitset<32> zero(0); 
bitset<32> ra(0); 
bitset<32> sp; 
bitset<32> gp; 
bitset<32> tp(0); 
bitset<32> t0(0); 
bitset<32> t1(0); 
void LUI(bitset<32>*rd, int imm){
    bitset<32> temp(imm); 
    for(int i=31; i>=12; i--){
        *rd[i]=temp[i];
    }
    for(int i=11; i>=0; i--){
        *rd[i]=0; 
    }
}

How can I update for example t1 through the function LUI() as dereferencing is not working? Here are the errors I get:

error: no match for 'operator*' (operand type is 'std::bitset<32>')
   46 |         *rd[i]=0;
 note:   candidate expects 2 arguments, 1 provided
   46 |         *rd[i]=0;
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Hadj Ahmed
  • 31
  • 5
  • *as dereferencing is not working* Your have forgot to show the code that doesn't work, and the errors. – 273K May 02 '23 at 07:35
  • 2
    `#include` -- Do not use this header. The correct header is `#include `. – PaulMcKenzie May 02 '23 at 07:38
  • @Hadj Ahmed At least instead of *rd[i] you have to write ( *rd )[i] – Vlad from Moscow May 02 '23 at 07:38
  • Take a look at [C++ Operator Precedence](https://en.cppreference.com/w/cpp/language/operator_precedence) – 273K May 02 '23 at 07:38
  • Simple answer is to use a reference not a pointer. – john May 02 '23 at 07:52
  • 1
    Some commonly accepted good practices: 1) Don't use global variables if not absolutely required. They make the code difficult to refactor and maintain. 2) `using namespace std` is also considered a bad practice. (https://stackoverflow.com/q/1452721) 3) Prefer references over pointers when the value is required (Devs. expect pointers to accept nullptr, which your function does not). 4) Avoid magic numbers in the code, as it make the code difficult to understand. 5) stdc++.h should be avoided (https://stackoverflow.com/q/31816095) 6) Choose descriptive variable names. – Adrian Maire May 02 '23 at 08:04
  • That LUI will crash anyway if to pass nullptr to it. If something can't be nullptr then accept reference. – Öö Tiib May 02 '23 at 08:15

2 Answers2

4

The function LUI as is does not make sense. I suppose it is only provided as an example of using the subscript operator with bitsets. Nevertheless you could pass to the function bitsets by reference instead of passing them through pointers

void LUI(bitset<32> &rd, int imm);

As for your problem then instead of

*rd[i]=temp[i];

or

*rd[i]=0;

you have to write

( *rd )[i]=temp[i];

( *rd )[i]=0;

or

rd->operator []( i ) = temp[i];
rd->operator []( i ) = 0;

The problem with your code is that the subscript operator has a higher priority than the dereferencing operator.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
3

Just to elaborate a bit upon comments and the other answer for the question.

To directly solve your issue with no other changes, you need to wrap your de-reference in parenthesis like this: (*rd)[i]. As for why you need to do this, it comes down to operator precedence (https://en.cppreference.com/w/cpp/language/operator_precedence) in cpp, [] (subscript) is evaluated before * indirection (de-referencing), as this is the case, you need to explicitly tell the compiler what you want to do first since otherwise you are directly calling the subscript operator on a pointer which is just an integer.

A recommendation that was made in the comments is to not use <bits/stdc++.h>. You only really want to use this if you are doing something like competitive programming as it is not part of the cpp standard; when using this you are not guaranteed to have it work on all or any compilers other than gcc.
An additional issue is that including unnecessary headers can slow down compiling.

A personal recommendation (and mentioned in the other answer) is to not use pointers, instead think about using references instead of pointers, this will remove any operator precedence issue while still gaining the ability to not copy memory. Here is the function with references:

void LUI(bitset<32>& rd, int imm) {
    bitset<32> temp(imm); 
    for(int i=31; i>=12; i--){
        rd[i]=temp[i];
    }
    for(int i=11; i>=0; i--){
        rd[i]=0; 
    }
}
EliSauder
  • 138
  • 1
  • 10
  • the actual problem about `bits/stdc++.h` is that it is non-standard, non-portable. – 463035818_is_not_an_ai May 02 '23 at 08:06
  • That is true, meant to include that; I will update that in the answer. Though, something being non-portable still isn't really a concern for competitive programming as all you are worried about is speed of implementation. Regardless... – EliSauder May 02 '23 at 08:09
  • I can do competitive coding and use a build chain that knows nothing about `bits/stdc++.h`. It has nothing to do with speed of execution – 463035818_is_not_an_ai May 02 '23 at 08:12
  • I agree, I personally don't use it, if I need something similar I make it myself. I actually try to never use things like that as I treat it as a quiz for remembering what headers I need. – EliSauder May 02 '23 at 08:17