Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
In C++:
static_cast<unsigned int>(reinterpret_cast<unsigned int>(&this[-0x00003111]))
I don't understand &this[-0x00003111]
I can't understand "[-address]"
How to convert it to delphi code?
This is a strange piece of code. To understand this the operator precedences have to be considered.
However, the important missing piece is the class to which this refers to. I assume this happens in a method of class A. The following code does the same like
static_cast<unsigned int>(reinterpret_cast<unsigned int>(&this[-0x00003111]))
but with separated expressions:
A *pThis = this;
A &a = pThis[-0x00003111]; // aka. A &a = *(pThis - 0x00003111);
A *pA = &a;
unsigned int ui = reinterpret_cast<unsigned int>(pA);
unsigned int ui2 = static_cast<unsigned int>(ui);
(To get this compiling at all, I had to use -fpermissive.)
Considering that 64 bit CPUs are very common nowadays, may be, it is worth to mention that the unsigned int may have 32 bits only where the this pointer has 64 bit in this case. So, the reinterpret_cast clips half of the bits away in this case.
Life Demo on coliru
Dear children.
Please, don't do this at home.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
After looking harder at the code, I figured out the answer to my question. I was mistaken in thinking the initial declaration of linked list meant all future types had to be the same
The code I am looking at is for linked list insertion. The linked list is used to store logical addresses. The linked list is defined as unsigned 32 bit, but the addresses being inserted are defined as void*.
A logical address is cast to paddr_t and is then inserted. paddr_t was used to be reverse compatible with 32bit or 64 bit systems, since the void* size changes.
When the paddr_t is passed to the insert function, will the insert function parameter be promoted to paddr_t? Will the linked list member be promoted as well once the insertion is complete?
Abbreviated example of the code
LinkedList <unsigned> foo;
unsigned bar = 1001;
void* Laddr = &bar;
foo.insert((paddr_t)Laddr);
Assuming a common-sense definition of LinkedList: You don't pass paddr_t to the insert function. You pass unsigned to the insert function. If you try to pass paddr_t, the compiler will add an (unsigned) cast for you, and may or may not emit a warning.
If paddr_t and unsigned are the same type, it's unlikely that you'll get a warning, and extremely likely that it will work fine.
If paddr_t is bigger than unsigned, and you have a paddr_t that doesn't fit in an unsigned, then the extra bits will be removed to make it fit in unsigned, and that number will be stored in the list, and whatever code get the number back out of the list and converts it back to paddr_t will not work properly because it gets the wrong number.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have recently got a basic idea of bit manipulation, and I was going through a problem where I found this C++ statement:
int popcount[1<<16];
I do have a basic idea of left/right Bit shift, but I would like to know why it is used in array size place.
Unless you find a comment in the code and unless you find out what the intent of popcount is, one can just guess why one writes 1 << 16 instead of, for example, 65536.
A common case could be that you want to count the number of occurrences of a particular id in, for example, a file. If the range of such an id where 16 bits, then such code could look as follows. The [1<<16] then expresses that you expect a range of not more than 16 bits:
int popcounts[1<<16] = { 0 };
int main() {
uint16_t id;
while (myfile >> id) {
popcounts[id]++;
}
}
Note that this is more accurate than writing int popcounts[UINT_MAX], because UINT_MAX is guaranteed to be equal or greater than 65536, and it is not guaranteed to be exactly 65536.
1<<16 is a common way to write 2 ** 16, which is easier to verify and modify than the "magic number" 65536. You may also encounter things like 1000 * 1000 instead of 1000000 for the same reason (although C++14 allows for 1000'000).
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I really want to use some void casts to hold binary data but this is either g++ warning cascade or a lot of casting. Is there an easy and safe way to do void pointer arithmetics in C++ (preferably c++11 or higher)?
I am working only on posix systems with gnu compiler so that not a problem here.
Usecase:
I have void * ptr to data with size > 1GB.
I have other function to do things, lets call it stuff() its part of external library and gets (void *, size_t) as params.
stuff(ptr, n) is likely to mutate underlying memory. basically I need to pass slice of ptr*.
Code suppose to, is, and i guess, will not be portable.
I guess i will go just with -Wno-pointer-arithmetics if i wont be able to find some more elegant solution, but the one proposed in answers helped
Depends on what you have in mind when asking about arithemtics. Following code is perfectly fine, and compilable by GNU g++ -std=c++11 :
#include <cstdlib>
#include <cstdio>
int main()
{
void * x = std::malloc(100);
std::printf("%p\n", x);
std::printf("%p\n", x+20);
return 0;
}
(Edit2)
Question is pretty confusing, but if gnu compiler is something to work on, void pointer arithmetics is perfectly ok. GNU basically defines void * as pointer with one byte increments, and by that all statements in above code are correct. I did not tested it with other compilers, and as far as this question is considered, I do not have to.
For compilers other than GNU, using unsigned integer type perfectly safe and correct : first cast pointer to either one of 1byte integer type:
size_t
uintptr_t / intptr_t
or if you know memory size and model - precise fixed width integer }
If ever memory addressing will be changed to any other weird size per cell - you would need to use type that after adding +1 to address will point to next physical storage cell.
Also to clarify = bool is not 1bit type... its padded (aliased) char with some wrapper magic inside.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
printf("bool: %zu; true: %zu; 1: %zu\n", sizeof (bool), sizeof true, sizeof 1);
The above piece of code yields
bool: 1; true: 1; 1: 4
I am fine with the sizeof(1), it is an integer and hence 4 bytes size.
But bool (and true) only needs a size of 1 "bit", still the output is 1 i.e. 1 byte.
Why is this so?
For an efficient (packed) representation use std::bitset:
#include <bitset>
std::bitset<2000000> my_bits;
Obviously this is for C++ only. In C you would have to implement this explicitly yourself, e.g.:
#include <stdint.h>
#include <limits.h>
uint8_t my_bits[2000000 / CHAR_BIT];
and then to access individual bits you would need to implement some simple inline functions using bitwise operations.
The minimum addressable unit is byte. Each object shall have its address. Also sizeof operator returns number of bytes occupied by an object. Even empty structures in C++ shall have non-zero sizes.
You can use standard class std::bitset instead of a boolean array.
An alternative to compile sized std::bitset<N> is to use the specialization std::vector<bool> which has a dynamic size. But care, it doesn't act as regular container as it provides proxy to access individual bit.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have 4 pin values defined P1_1, P1_2, P1_3, P1_4, with bit values. (1/0)
I want to combine them into one byte value, example:
0000 0101 (3 LSB are the pins)
How can i do this?
Something like
value = (P1_1<<3)|(P1_2<<2)|(P1_3<<1)|(P1_4);
Disclaimers: this is pretty ugly example. In your actual code you probably want some kind of constants defined for shift (so you are able to do the reverse operation without using more magic literal values).
Also note that this will have unexpected results if one of P constants is not 0 or 1. In this case one might use something like !!P1_x instead of P1_x.
bitset<4> temp;
temp[0] = P1_1;
temp[1] = P1_2;
temp[2] = P1_3;
temp[3] = P1_4;
unsigned char value = static_cast<unsigned char>(temp.to_ulong());