read bits from pointer to array of unsigned char - c

Say I have an array of unsigned char of 6 bytes.
And some function modifies value in it. How would I retrieve modified values say from 0-19bit?
void my_func()
{
unsigned char tempVal[6] = { 0,0,0,0,0,0}
unsigned char* temPtr = &temVal; // Say I am using pt
int newVal;
// call external function to modify value
// fun below assign new values to tempVal[0].. till tempVal[5].
void someFuncTomodifyVal( tempPtr );
// Now I want values from say 1st19bits
// how would I achieve that? I know I have to use And condtion with 7FFFF
// so say somthing like
newValue = *tempPtr & 0x7FFFF // but then *tempPtr will give me first byte only?
}
So my question is what should I give instead of *tempPtr to get 1st 19 bits
example of
void someFuncTomodifyVal( unsigned char m[] )
{
m[0] = 'some value retrieve from other funct'
m[1] = ' values based on some cal'
m[2] = ' values based on some cal'
}

The main issue here is that you can't take a pointer to unsigned char and wildly cast it to a larger pointer type. This would result in a strict aliasing violation - undefined behavior. This can give incorrectly generated code and similar evil bugs.
To dodge this and access the array through a pointer, you could use a container type that contains the same type among its members:
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <inttypes.h>
typedef union
{
unsigned char u8 [6];
uint32_t u32;
} my_union_t;
int main()
{
unsigned char tempVal[6] = { 0x11,0x22,0x33,0x44,0x55,0x66};
my_union_t* mu = (my_union_t*)tempVal;
printf("%"PRIx32"\n", mu->u32 & 0x7FFFF);
}
As for what this will print, it depends on CPU endianess - the code is not portable. On my 32 bit little endian CPU I get 32211.

You probably intended to achieve something like this:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
unsigned char tempVal[6] = { 0x1,0x2,0x3,0x4,0,0 };
uint32_t *temPtr = (uint32_t *)tempVal; // Say I am using pt
uint32_t newVal = *temPtr;
printf("%08x\n", newVal);
newVal &= 0x7ffff;
printf("%08x\n", newVal);
}
On a little endian system the output will be:
04030201
00030201
On a big endian system the output will be:
01020304
01020304
Be aware that this is not portable as it depends on the endianness of the target system and it also violates the strict aliasing rule
Portable and correct solution:
#include <stdio.h>
#include <stdint.h>
int main(void)
{
unsigned char tempVal[6] = { 0x1,0x2,0x3,0x4,0,0 };
uint32_t value = 0;
for (int i = 0; i < 4; i++)
{
value <<= 8;
value |= tempVal[i];
}
printf("%08x\n", value);
value &= 0x7ffff;
printf("%08x\n", value);
}

Wrong answer
You can use a type which can store the 19 bits. Example : uint32_t *n = (uint32_t *) tempVal;. Now you can get the desired bits (*n) & 0x7FFFF
Good answer
You can use union to respect strict aliasing :
union foo {
unsigned char tmp[6];
unsigned int n;
};

Related

C vs C++ placing structs in unsigned char buffer

Does C have anything similar to C++ where one can place structs in an unsigned char buffer as is done in C++ as shown in the standard sec. 6.7.2
template<typename ...T>
struct AlignedUnion {
alignas(T...) unsigned char data[max(sizeof(T)...)];
};
int f() {
AlignedUnion<int, char> au;
int *p = new (au.data) int; // OK, au.data provides storage
char *c = new (au.data) char(); // OK, ends lifetime of *p
char *d = new (au.data + 1) char();
return *c + *d; // OK
}
In C I can certainly memcpy a struct of things(or int as shown above) into an unsigned char buffer, but then using a pointer to this struct one runs into strict aliasing violations; the buffer has different declared type.
So suppose one would want to replicate the second line in f the C++ above in C. One would do something like this
#include<string.h>
#include<stdio.h>
struct Buffer {
unsigned char data[sizeof(int)];
};
int main()
{
struct Buffer b;
int n = 5;
int* p = memcpy(&b.data,&n,sizeof(int));
printf("%d",*p); // aliasing violation here as unsigned char is accessed as int
return 0;
}
Unions are often suggested i.e. union Buffer {int i;unsigned char b[sizeof(int)]}; but this is not quite as nice if the aim of the buffer is to act as storage (i.e. placing different sized types in there, by advancing a pointer into the buffer to the free part + potenially some more for proper alignment).
Have you tried using a union?
#include <string.h>
#include <stdio.h>
union Buffer {
int int_;
double double_;
long double long_double_;
unsigned char data[1];
};
int main() {
union Buffer b;
int n = 5;
int *p = memcpy(&b.data, &n, sizeof(int));
printf("%d", *p); // aliasing violation here as unsigned char is accessed as int
return 0;
}
The Buffer aligns data member according the type with the greatest alignment requirement.
Yes, because of strict aliasing rule it is just not possible. As it is not possible to write a standard compliant malloc().
Your buffer is not aligned - alignas(int) from stdalign.h needs to be added.
If you want to protect against compiler optimizations, either:
just cast the pointer and access it and compile with -fno-strict-aliasing, or use volatile
or move the accessor to the buffer to another file that is compiled without LTO so that compiler just is not able to optimize it.
// mybuffer.c
#include <stdalign.h>
alignas(int) unsigned char buffer[sizeof(int)];
void *getbuffer() { return buffer; }
// main.c
#include <string.h>
#include <stdio.h>
#include "mybuffer.h"
int main() {
void *data = getbuffer();
// int *p = new (au.data) int; // OK, au.data provides storage
int *p = data;
// char *c = new (au.data) char(); // OK, ends lifetime of *p
char *c = data;
*c = 0;
// char *d = new (au.data + 1) char();
char *d = (char*)data + 1;
*d = 0;
return *c + *d;
}
The way the definition of Effective Type in 6.5p6 is written, it's unclear what it's supposed to mean in all corner cases--likely because there was never a consensus among Committee Members as to how all corner cases should be handled. Defect reports often add more confusion than clarity, since they use terms like the "active member" of a union when neither the Standard nor the defect reports specify what actions would set or change it.
If one wants to use an object of static or automatic duration as though it were a buffer without a declared type, a safe way of doing that should be to do something like the following:
void volatile *volatile dummy_vp;
void test(void)
{
union {
char dat[1000];
unsigned long force_alignment;
} buffer;
void *volatile launder = buffer.dat;
dummy_vp = &launder;
void *storage_blob = launder;
...
}
Unless an implementation goes out of its way to test whether the read of
launder happened to yield an address matching buffer.dat, it would have no way of knowing whether the object at that address had a declared type. Nothing in the Standard would forbid an implementation from behaving nonsensically if the address happened to match that of buffer.dat, but situations where performance improvements would justify the cost of the check aren't likely to be common enough for compilers to attempt such "optimization".

Converting any variable from big to little endian - how to avoid void pointers?

I'm working on an application that needs to convert any type of the variable from big to little-endian.
My system works with different variable types (16, 32, and 64 bits wide), and I need to be able to change the endianness with a single function. I wrote a function that manages to swap bytes in any variable however, I'm not happy with it. It works, but it requires dereferencing void pointers, which are prone to error with the double star...
Is there any better way to approach the problem?
Is there any way to avoid void pointers as return value? I was thinking about switch-case loop (eg. case 4 bytes -> return int32) however, I don't know how to write a function prototype for a function that returns different values.
My function:
void* swapBytes(void* number, int bytes_num){
void* swapped;
unsigned __int8* single_byte_ptr;
swapped = malloc(bytes_num * sizeof(__int8));
for (int i = 0; i<bytes_num; i++){
single_byte_ptr =((unsigned __int8*)number)+i; //get current byte
*( (__int8*)(swapped)+((bytes_num-1)-i)) = (unsigned __int8)*single_byte_ptr; //save the byte in new position
}
return swapped;
}
the way I call this function
__int64 big_number = 35169804487071;
big_number = *(__int64*)(swapBytes(&big_number, 8));
One problem you have is that you're leaking memory. You return a pointer to malloc'ed memory, but you're not saving the pointer when you return.
Given that you're assigning the result back to the same value, you're better off updating the existing variable, swapping the current byte with a byte on the "opposite" side.
You also don't need to use a void * anyplace other than the parameter type. Inside of the function, just use a pointer to an unsigned char or unsigned __int8 to work through the bytes.
void swapBytes(void* number, int bytes_num)
{
unsigned __int8* ptr = number;
for (int i = 0; i<bytes_num/2; i++) {
unsigned __int8 tmp = ptr[i];
ptr[i] = ptr[bytes_num-1-i];
ptr[bytes_num-1-i] = tmp;
}
}
Then call it like this:
swapBytes(&big_number, sizeof(big_number));
Your solution is very over-engineered and also entirely unsuitable for embedded systems such as MPC57xx.
Any integer type can get safely iterated across using a pointer to character. Assuming uint8_t* is a character type for your compiler, it's as simple as this:
void little_to_big16 (uint8_t big [sizeof(uint16_t)],
const uint8_t little [sizeof(uint16_t)])
{
big[0] = little[1];
big[1] = little[0];
}
Then write big_to_little16, big_to_little32 etc etc as needed. Such functions can and should probably be inlined too.
Example of use:
#include <stdio.h>
#include <inttypes.h>
void little_to_big16 (uint8_t big [sizeof(uint16_t)],
const uint8_t little [sizeof(uint16_t)])
{
big[0] = little[1];
big[1] = little[0];
}
int main (void)
{
uint16_t little = 0xAABB;
uint16_t big;
little_to_big16((uint8_t*)&big, (uint8_t*)&little);
printf("%"PRIx16, big);
}
Output on x86 little endian:
bbaa

C struct, variables with different bit sizes

I'm not sure how to create a Struct in C with its variables having different bit sizes, for example:
I want to create a struct with one variable as an 8-bit integer, one variable as an 16-bit boolean, one as an 8-bit boolean, one as a 32-bit floating point number etc.
I'm coming from java so all this is very confusing, thanks.
#include <stdio.h>
#include<stdbool.h>
struct{
float d; // By default 32 bits are initialized
unsigned int a: 8;
bool my_bool_8;
bool my_bool_16;
}nibble;
int main()
{
printf("Size of structure is %lu\n", sizeof(nibble));
printf("Size of my_bool_8 is %zu\n", sizeof(nibble.my_bool_8));
return 0;
}
It depends from compiler and platform. For 8-bit integer, perhaps, you can use "int8_t" type. For 32-bit floating point - "float", but you must read documentation for your compiler.
Maybe this small example response your question:
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
struct {
uint8_t my_int_8;
int16_t my_bool_16;
bool my_bool_8;
float my_float;
} test;
int main(const int argc, const char* argv[]) {
printf("sizeof(my_int_8)=%zu\n", sizeof(test.my_int_8));
printf("sizeof(my_bool_16)=%zu\n", sizeof(test.my_bool_16));
printf("sizeof(my_bool_8)=%zu\n", sizeof(test.my_bool_8));
printf("sizeof(my_float)=%zu\n", sizeof(test.my_float));
}

Further question with memory mapped interface

I still have some issues with my c code that deals with an memory mapped device.
At the moment I declare the address space for the registers I write as volatile
pointer and I write data to them as shown below:
volatile unsigned int *wr_register = (int *) 0x40000000;
volatile unsigned int *c_register = (int *) 0x40000100;
...
main{
*wr_register = 0x01234567;
*c_register = 0x01234567;
*(c_register+1) = 0x89abcdef;
}
This works more or less fine. However, I would like to have specific read and
write functions that interact with the memory mapped registers. So ideally,
it would look something like this:
const unsigned int wr_register = 0x40000000;
const unsigned int c_register = 0x40000100;
function write_REG(unsigned int address, int offset, int data)
{
(unsigned int*) (address + offset) = data;
}
main{
*write_REG(0x40000000, 0, 0x01234567);
*write_REG(0x40000100, 0, 0x01234567);
*write_REG(0x40000100, 1, 0x89abcdef);
}
I have not tried it out yet to be honest, but I am wondering if somebody could
tell me if this is a proper way to do it?
EDIT: Maybe it is of use for someone else, here I have my function and they seem to work. Many thanks for the helpful comments!
void reg_write(unsigned int address, int offset, int data)
{
*((volatile unsigned int*)address + offset) = data;
}
int reg_read(unsigned int address, int offset)
{
return(*((volatile unsigned int*)address + offset));
}
Many thanks
There are quite a few problems with your code:
I assume you meant void where you wrote function.
You should make the pointer inside the function to be volatile as well.
You should dereference the pointer before writing the data. The * should be inside the function, not at the call site (*write_REG) as it is now - that would be a compile error.
You should add the offset to the pointer, not the address. This is because an offset of 1 is meant to be the next int which could be, say, 4 bytes away, but adding it to the address will only add 1 byte.
Your corrected function should look like this:
void write_REG(unsigned int address, int offset, int data)
{
*((volatile unsigned int*)address + offset) = data;
}
and you would call it like:
write_REG(0x40000000, 0, 0x01234567);
That would be just fine IMHO. I sometimes use macros like:
#define WR_REG *(volatile unsigned int*)0x40000000
This allows the registers to be used sort of like variables:
WR_REG = 0x12345678;

size of a datatype without using sizeof

I have a data type, say X, and I want to know its size without declaring a variable or pointer of that type and of course without using sizeof operator.
Is this possible? I thought of using standard header files which contain size and range of data types but that doesn't work with user defined data type.
To my mind, this fits into the category of "how do I add two ints without using ++, += or + ?". It's a waste of time. You can try and avoid the monsters of undefined behaviour by doing something like this.
size_t size = (size_t)(1 + ((X*)0));
Note that I don't declare a variable of type or pointer to X.
Look, sizeof is the language facility for this. The only one, so it is the only portable way to achieve this.
For some special cases you could generate un-portable code that used some other heuristic to understand the size of particular objects[*] (probably by making them keep track of their own size), but you'd have to do all the bookkeeping yourself.
[*] Objects in a very general sense rather than the OOP sense.
Well, I am an amateur..but I tried out this problem and I got the right answer without using sizeof. Hope this helps..
I am trying to find the size of an integer.
int *a,*s, v=10;
a=&v;
s=a;
a++;
int intsize=(int)a-(int)s;
printf("%d",intsize);
The correct answer to this interview question is "Why would I want to do that, when sizeof() does that for me, and is the only portable method of doing so?"
The possibility of padding prevent all hopes without the knowledge of the rules used for introducing it. And those are implementation dependent.
You could puzzle it out by reading the ABI for your particular processor, which explains how structures are laid out in memory. It's potentially different for each processor. But unless you're writing a compiler it's surprising you don't want to just use sizeof, which is the One Right Way to solve this problem.
if X is datatype:
#define SIZEOF(X) (unsigned int)( (X *)0+1 )
if X is a variable:
#define SIZEOF(X) (unsigned int)( (char *)(&X+1)-(char *)(&X) )
Try this:
int a;
printf("%u\n", (int)(&a+1)-(int)(&a));
Look into the compiler sources. You will get :
the size of standard data types.
the rules for padding of structs
and from this, the expected size of anything.
If you could at least allocate space for the variable, and fill some sentinel value into it, you could change it bit by bit, and see if the value changes, but this still would not tell you any information about padding.
Try This:
#include<stdio.h>
int main(){
int *ptr = 0;
ptr++;
printf("Size of int: %d",ptr);
return 0;
Available since C89 solution that in user code:
Does not declare a variable of type X.
Does not declare a pointer to type X.
Without using sizeof operator.
Easy enough to do using standard code as hinted by #steve jessop
offsetof(type, member-designator)
which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the structure member ..., from the beginning of its structure ... C11 ยง7.19 3
#include <stddef.h>
#include <stdio.h>
typedef struct {
X member;
unsigned char uc;
} sud03r_type;
int main() {
printf("Size X: %zu\n", offsetof(sud03r_type, uc));
return 0;
}
Note: This code uses "%zu" which requires C99 onward.
This is the code:
The trick is to make a pointer object, save its address, increment the pointer and then subtract the new address from the previous one.
Key point is when a pointer is incremented, it actually moves by the size equal to the object it is pointing, so here the size of the class (of which the object it is pointing to).
#include<iostream>
using namespace std;
class abc
{
int a[5];
float c;
};
main()
{
abc* obj1;
long int s1;
s1=(int)obj1;
obj1++;
long int s2=(int)obj1;
printf("%d",s2-s1);
}
Regards
A lot of these answers are assuming you know what your structure will look like. I believe this interview question is intended to ask you to think outside the box. I was looking for the answer but didn't find any solutions I liked here. I will make a better assumption saying
struct foo {
int a;
banana b;
char c;
...
};
By creating foo[2], I will now have 2 consecutive foo objects in memory. So...
foo[2] buffer = new foo[2];
foo a = buffer[0];
foo b = buffer[1];
return (&b-&a);
Assuming did my pointer arithmetic correctly, this should be the ticket - and its portable! Unfortunately things like padding, compiler settings, etc.. would all play a part too
Thoughts?
put this to your code
then check the linker output ( map file)
unsigned int uint_nabil;
unsigned long ulong_nabil;
you will get something like this ;
uint_nabil 700089a8 00000004
ulong_nabil 700089ac 00000004
4 is the size !!
One simple way of doing this would be using arrays.
Now, we know for the fact that in arrays elements of the same datatype are stored in a contiguous block of memory. So, by exploiting this fact I came up with following:
#include <iostream>
using namespace std;
int main()
{
int arr[2];
int* ptr = &arr[0];
int* ptr1 = &arr[1];
cout <<(size_t)ptr1-(size_t)ptr;
}
Hope this helps.
Try this,
#define sizeof_type( type ) ((size_t)((type*)1000 + 1 )-(size_t)((type*)1000))
For the following user-defined datatype,
struct x
{
char c;
int i;
};
sizeof_type(x) = 8
(size_t)((x*)1000 + 1 ) = 1008
(size_t)((x*)1000) = 1000
This takes into account that a C++ byte is not always 8 binary bits, and that only unsigned types have well defined overflow behaviour.
#include <iostream>
int main () {
unsigned int i = 1;
unsigned int int_bits = 0;
while (i!=0) {
i <<= 1;
++int_bits;
}
unsigned char uc = 1;
unsigned int char_bits = 0;
while (uc!=0) {
uc <<= 1;
++char_bits;
}
std::cout << "Type int has " << int_bits << "bits.\n";
std::cout << "This would be " << int_bits/8 << " IT bytes and "
<< int_bits/char_bits << " C++ bytes on your platform.\n";
std::cout << "Anyways, not all bits might be usable by you. Hah.\n";
}
Surely, you could also just #include <limit> or <climits>.
main()
{
clrscr();
int n;
float x,*a,*b;//line 1
a=&x;
b=(a+1);
printf("size of x is %d",
n=(char*)(b)-(char*)a);
}
By this code script the size of any data can be calculated without sizeof operator.Just change the float in line 1 with the type whose size you want to calculate
#include <stdio.h>
struct {
int a;
char c;
};
void main() {
struct node*temp;
printf("%d",(char*)(temp+1)-(char*)temp);
}
# include<stdio.h>
struct node
{
int a;
char c;
};
void main()
{
struct node*ptr;
ptr=(struct node*)0;
printf("%d",++ptr);
}
#include <bits/stdc++.h>
using namespace std;
int main()
{
// take any datatype hear
char *a = 0; // output: 1
int *b = 0; // output: 4
long *c = 0; // output: 8
a++;
b++;
c++;
printf("%d",a);
printf("%d",b);
printf("%d",c);
return 0;
}

Resources