/
Help i have a question
/
i have found this register uint32_t hmagic[3] asm("r12");
/
if i write like that the register keyword doesnt get the warning anymore do this really place a variable in a register?
DaviChan
You are confusing undefined behavior with implementation defined behavior i guess.
https://en.cppreference.com/w/cpp/language/ub Take a look at the "unspecified behavior" point. That definition was what I was beeing taught. But yeah, i think we have a diffetent definition. Note for the future: make sure we have the same definitions of things before arguing about them ^^
Anonymous
https://en.cppreference.com/w/cpp/language/ub Take a look at the "unspecified behavior" point. That definition was what I was beeing taught. But yeah, i think we have a diffetent definition. Note for the future: make sure we have the same definitions of things before arguing about them ^^
Once again, you are not talking about Unspecified Behavior but Implementation Defined Behavior. You can't rely on Unspecified Behavior because an implementation is not required to document it. If you rely on Unspecified Behavior, a compiler upgrade or changing compilers on the same architecture can cause your program to misbehave or behave differently. Relying on Implementation Defined Behavior is ok because the implementation documents this behavior. But however you affect portability of your code and are tied to the implementation. Undefined Behavior on the other hand makes your code completely wrong. Your program may behave differently in consecutive runs of the program and nothing is guaranteed in this case
/
help i have another question
/
how i do this uint8_t *ch_info = new uint8_t[ chsize ]; without using new
/
i mean that i want to use restrict on it but i cant on an array
Anonymous
i have found this register uint32_t hmagic[3] asm("r12");
Register keyword though applicable in C doesn't have any meaning in C++. Even in C, you should not be using it unless you are programming in embedded environments. Your compiler will know better about optimizations like this and you should learn to trust it.
Anonymous
yes but if i am making something like embedded environments how i do it in c++
C++ doesn't support it. So you can't. If your compiler supports it as an extension, you can use it.
/
C++ doesn't support it. So you can't. If your compiler supports it as an extension, you can use it.
i have this code ch_info += 4; uint32_t str_size = *(uint32_t *)ch_info; ch_info += 4; sf.software = new char[str_size]; memcpy( sf.software, (const char*)ch_info, str_size ); break; ch_info is this auto * __restrict__ ch_info = new uint8_t[ chsize ];
/
C++ doesn't support it. So you can't. If your compiler supports it as an extension, you can use it.
but in assembly it still puts the pointer in the memory every time mov ebx, [ebp+var_4C] mov eax, [ebp+ptr] add eax, 4 mov [ebp+ptr], eax mov eax, [ebp+ptr] mov eax, [eax] mov [ebp+var_3C], eax mov eax, [ebp+ptr] add eax, 4 mov [ebp+ptr], eax mov ecx, [ebp+var_3C] mov eax, esp mov [eax], ecx call __Znaj ; operator new[](uint) mov ecx, eax ; } // starts at 10687 mov [ebp+var_5C], ecx jmp $+5
Anonymous
i have used restrict why it doesnt work
Do you know what restrict is used for?
Anonymous
i searched
What is your understanding of it then?
/
Do you know what restrict is used for?
as i understanded its to tell the compiler that a pointer will point to something that will be pointed by only one pointer during the pointer lifetime
/
Do you know what restrict is used for?
and i readed that if it knows it may also put the pointer in a register because it have not to update the aliases
Anonymous
as i understanded its to tell the compiler that a pointer will point to something that will be pointed by only one pointer during the pointer lifetime
Yes. So why do you think the compiler should not read the memory pointed to by the pointer? Restrict is just used to help with compiler optimizations. If the compiler can figure out that the pointed to memory was not changed, then it may not load the memory again. But if you change the pointed to memory using that pointer, then the compiler can no longer do this optimization and may have to read the pointed to value from memory again. So this depends on your code.
Anonymous
wait so how should i make it optimize
By not changing the memory using that pointer and by increasing the optimization level of your compiler.
/
By not changing the memory using that pointer and by increasing the optimization level of your compiler.
i am adding 4 to the pointer but it gets the pointer from the memory adds 4 to it and puts it again
/
By not changing the memory using that pointer and by increasing the optimization level of your compiler.
i mean why it does this mov eax, [ebp+ptr] add eax, 4 mov [ebp+ptr], eax mov eax, [ebp+ptr] mov eax, [eax] when it can do this add eax, 4 mov eax, [eax]
Anonymous
i am not changing the memory
First of all your code is wrong in the sense that you are violating the restrict keyword. You are breaking strict aliasing rules by using a cast to uint32_t * pointer even though it's is just for a read. This is not correct. Moreover, restrict is a hint to the compiler. The compiler can ignore it. At best you can increase the optimization level of your compiler to see if it works. Increase the optimization level to O3.
Anonymous
but how i dont violate the strict aliasing rule
(uint32_t*) ch_info This is how. If you must do something like this in C, using a union is the recommended way
Anonymous
is it how to violate it
I don't understand what you are asking
/
(uint32_t*) ch_info This is how. If you must do something like this in C, using a union is the recommended way
but i am doing in that way because it is a buffer of many bytes and i read them as int32
Anonymous
but i am doing in that way because it is a buffer of many bytes and i read them as int32
This is Undefined Behavior. Read about strict aliasing rules and how you can break it without even knowing about it. https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
Anonymous
/
Read the link above
you mean this union { Msg msg; unsigned int asBuffer[sizeof(Msg)/sizeof(unsigned int)]; };
Anonymous
you mean this union { Msg msg; unsigned int asBuffer[sizeof(Msg)/sizeof(unsigned int)]; };
Yes something like this but in your case the members would be uint32_t and an array of uint8_t of size 4
/
union { uint32_t u32; uint8_t u8[4]; ]
Anonymous
can you show me the example
I can't code on my phone. So unfortunately no. But your union would look like this typedef union { uint32_t a; uint8_t b[4]; } Buffer; This would work in C but not in C++. In C++, accessing a union member that was not the last one set is Undefined Behavior.
Anonymous
and i am reading from a bigger buffer that i dont know how big it is
Why can't you declare a dynamic array of uint32_t then, instead of uint8_t and then trying to reinterpret that uint8_t array as a uint32_t? How is your buffer populated? You ask many questions without giving complete details of what it is that you are trying to do.
/
How do you know when yo read an int16 or an int32?
because i know the structure of the file
Anonymous
How do you know when yo read an int16 or an int32?
And assuming you know how to read it correctly, you can do this: uint32_t a; fileStream.read(reinterpret_cast<char*>(&a), sizeof(a)); This is safe.
/
so i made one buffer containing the entire section
/
and i use a pointer to move in that
Anonymous
yes but then i have to call read every time i want to read something
Calling read multiple times the way I suggested is the only guaranteed to work solution. Any other solution like populating a buffer of bytes and then reading in different values by casting pointers is not a portable solution. Nor is it guaranteed to work on machines with strict alignment requirements As far as your question about restrict keyword is concerned, it is an optimization hint like I suggested earlier. Try increasing your compiler's optimization level (for gcc and clang you can pass -O3) to see if the compiler can optimize a restricted pointer by storing it in a register. It may or may not work. You can't force the compiler to do it. Maybe another way to force it would be to use const_cast on the pointer to the buffer of bytes to make it a pointer to a const buffer. That might force the compiler to use a register. But regardless of all these, it doesn't change the fact that this is Undefined Behavior in C++ though it may work.
Anonymous
so is it also bad to do this uint32_t info_hdr[3]; read_bytes (( char * ) info_hdr, 12 ); if ( info_hdr[0] != 0x5453494C || info_hdr[2] != 0x4F464E49 { return 2; }
This is fine depending on what does read_bytes does? Where is it reading from? If it is reading from a char* buffer populated by reading from a file, then you would essentially be doing the same thing underneath though it is masked by read_bytes in this case The C++ standard library guarantees that reading a stored int from a file into a char buffer aliased into another int works. But this is not guaranteed to work when you do the buffering and aliasing yourself.
Mahmoud
Can someone send exercises in function arrays (c++) I want to practice
Mahmoud
Where can I find good exercises to solve ?
кар карыч
how to implement so that, depending on the entered number, more numbers can be entered, and their number will be equal to the entered first number
кар карыч
3 1 2 3
кар карыч
++
neovstan
int count{}; std::cin >> count; for (int i = 0; i < count; ++i) { int number{}; std::cin >> number; }
neovstan
<3 thx bro
If you don't understand list-initialization by braces {} so far, you can use just = 0
кар карыч
Ok
neovstan
Ok
Though you don't have to initialize them if you want, but it's recommended to do so, 'cause if you didn't initialize them and then try to use them before you get their values from the user's input, it will be undefined behavior
neovstan
(except of int i = 0, the counter should be initialized anyway)
кар карыч
What variables are these numbers stored in?
кар карыч
Like how to use them later