In bellow example why we should use int32_t instead of uint32_t ? (platform is ARM 32 bit microcontroller)
struct tcb{
int32_t *stackPt;
struct tcb *nextPt;
};
It's a part of RTOS tutorial. and tcb is for thread control block .
why we should use int32_t* for stack ?
There is no particular reason that you should use pointer to signed rather than unsigned.
You are probably never going to dereference this pointer directly to access the words on the stack. If you do want to access the data on the stack, some of it will be signed, some unsigned, and some neither (strings etc) so the pointer type will not help you with that.
When you want to pass around a pointer but never dereference it then one convention is to use a pointer to void, but that convention isn't so popular in embedded system code.
One reason to use a pointer to a 32-bit integer is to suggest that the pointer is at least word-aligned. If you intend on complying with the ARM EABI (which you should) then the stack should be doubleword (64-bit) aligned at the entry to every EABI compliant function. To hint that that is the case you might want to even use a (u)int64_t pointer. This might be misleading though because not everything on the stack is 64-bit or 32-bit aligned, just the whole frames.
Related
According to the Golang tour, we're provided with the following integer types:
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
In theory, that means we could also have pointers to all of these types as follows:
*int *int8 *int16 *int32 *int64
*uint *uint8 *uint16 *uint32 *uint64 *uintptr
If this is the case, then we already have a pointer to a uint in the form of *uint. That would make uintptr redundant. The official documentation doesn't shed much light on this:
uintptr is an integer type that is large enough to hold the bit pattern of any pointer.
As I understand it, that means that the bit width of a uint is determined at compile time based on the target architecture (typically either 32-bit or 64-bit). It seems logical that the pointer width should scale to the target architecture as well (IE: a 32-bit *uint points to a 32-bit uint). Is that the case in Golang?
Another thought was that maybe uintptr was added to make the syntax less confusing when doing multiple indirection (IE: foo *uinptr vs foo **uint)?
My last thought is that perhaps pointers and integers are incompatible data types in Golang. That would be pretty frustrating since the hardware itself doesn't make any distinction between them. For instance, a "branch to this address" instruction can use the same data from the same register that was just used in an "add this value" instruction.
What's the real point (pun intended) of uintptr?
The short answer is "never use uintptr". 😀
The long answer is that uintptr is there to bypass the type system and allow the Go implementors to write Go runtime libraries, including the garbage collection system, in Go, and to call C-callable code including system calls using C pointers that are not handled by Go at all.
If you're acting as an implementor—e.g., providing access to system calls on a new OS—you'll need uintptr. You will also need to know all the special magic required to use it, such as locking your goroutine to an OS-level thread if the OS is going to do stack-ish things to OS-level threads, for instance. (If you're using it with Go pointers, you may also need to tell the compiler not to move your goroutine stack, which is done with special compile-time directives.)
Edit: as kostix notes in a comment, the runtime system considers an unsafe.Pointer as a reference to an object, which keeps the object alive for GC. It does not consider a uintptr as such a reference. (That is, while unsafe.Pointer has a pointer type, uintptr has integer type.) See also the documentation for the unsafe package.
uintptr is simply an integer representation of a memory address, regardless of the actual type it points to. Sort of like void * in C, or just casting a pointer to an integer. It's purpose is to be used in unsafe black magic, and it is not used in everyday go code.
You are conflating uintptr and *uint. uintptr is used when you're dealing with pointers, it is a datatype that is large enough to hold a pointer. It is mainly used for unsafe memory access, look at the unsafe package. *uint is a pointer to an unsigned integer.
I get the impression that Rust is intended to be used in highly safe systems. Then I noticed that raw pointers allow arbitrary pointer arithmetic, and they can cause memory safety and security issues.
Basically, a pointer is an object that refers to another object. In most programming languages (I guess) a pointer is actually just a number that refers to a memory address. Rust's raw pointers are really just that - memory addresses. There are other pointer types in Rust (& references, Box, Rc, Arc), for which the compiler can verify that the memory is valid and contains what the program thinks it contains. This is not the case for raw pointers; they can in principle point to any memory location, regardless of the content. Refer to The Book for more details.
Raw pointers can only be dereferenced inside unsafe blocks. These blocks are a way for the programmer to tell the compiler "I know better than you that this is safe and I promise not to do anything stupid".
It is generally best to avoid raw pointers if possible because the compiler cannot reason about their validity, which makes them unsafe in general. Things that make raw pointers unsafe are the potential to...
access a NULL pointer,
access a dangling (freed or invalid) pointer,
free a pointer multiple times,
All these points boil down to dereferencing the pointer. That is, to use the memory pointed to.
However, using raw pointers without dereferencing them is perfectly safe. This has a use case in finding out if two references point to the same object:
fn is_same(a: &i32, b: &i32) -> bool {
a as *const _ == b as *const _
}
Another use case is the foreign function interface (FFI). If you wrap a C function that takes raw pointers as arguments, there is no way around providing them to the function. This is actually unsafe (as is the whole FFI business), because the function is likely to dereference the pointer. This means you are responsible for making sure the pointer is valid, stays valid, and is not freed multiple times.
Finally, raw pointers are used for optimization. For example, the slice iterator uses raw pointers as internal state. This is faster than indices because they avoid range checks during iteration. However, it is also unsafe as far as the compiler is concerned. The library author needs to pay extra attention, so using raw pointers for optimization always comes at the risk of introducing memory bugs that you normally do not have in rust.
In summary, the three main uses of raw pointers are:
"just numbers" - you never access the memory they point to.
FFI - you pass them outside Rust.
memory-mapped I/O - to trigger I/O actions you need to access hardware registers at fixed addresses.
performance - they can be faster than other options, but the compiler won't enforce safety.
As to when raw pointers should be used, the first three points are straight-forward: You will know when they apply because you have to. The last point is more subtle. As with all optimizations, only use them when the benefit outweighs the effort and risk of using them.
A counter example when not to use raw pointers is whenever the other pointer types (& references, Box, Rc, Arc) do the job.
Given the following struct:
type Exp struct {
foo int,
bar *int
}
What is the difference in term of performance when using a pointer or a value in a struct. Is there any overhead or this just two schools of Go programming?
I would use pointers to implement a chained struct but is this the only case we have to use pointers in struct in order to gain performance?
PS: in the above struct we talk about a simple int but it could be any other type (even custom one)
Use the form which is most functionally useful for your program. Basically, this means if it's useful for the value to be nil, then use a pointer.
From a performance perspective, primitive numeric types are always more efficient to copy than to dereference a pointer. Even more complex data structures are still usually faster to copy if they are smaller than a cache line or two (under 128 bytes is a good rule of thumb for x86 CPUs).
When things get a little larger, you need to benchmark if performance concerns you. CPUs are very efficient at copying data, and there are so many variables involved which will determine the locality and cache friendliness of your data, it really depends on your program's behavior, and the hardware you're using.
This is an excellent series of articles if you want to better understand the how memory and software interact: "What every programmer should know about memory".
In short, I tell people to choose a pointer or not based on the logic of the program, and worry about performance later.
Use a pointer if you need to pass something to be modified.
Use a pointer if you need to determine if something was unset/nil.
Use a pointer if you are using a type that has methods with pointer receivers.
If the size of a pointer is less than the struct member, then using a pointer is more efficient since you don't need to copy the member but just its address. Also, if you want to be able to move or share some part of a structure, it is better to have a pointer so that you can, again, only share the address of the member. See also the golang faqs.
As described in this MSDN article, Microsoft has these two type annotations to declare native pointers on different architectures. However, on the second line:
On a 32-bit system, a pointer declared with __ptr64 is truncated to a 32-bit pointer. On a 64-bit system, a pointer declared with __ptr32 is coerced to a 64-bit pointer.
This sounds to me like the declaration doesn't matter; if the architecture overrides the declaration of __ptrXX to be the default anyways, what's the point of marking __ptrXX in the first place?
I see that this answer says that it's for interop, but if the declarations are essentially overridden as above, how does that help with interop?
There's a big difference between declaring and assigning a 32-bit pointer and actually using it. In other words, dereferencing the pointer. If you do that in a 64-bit process then there is no other option but to sign-extend it to a 64-bit pointer. Which is what "coerced" means. That may work by accident, but you'd have to be pretty lucky. It just doesn't make sense to try.
The point of declaring a __ptr32 is as described in that linked answer, it only makes sense when you interop with a 32-bit process. Which uses 32-bit pointers. It is not common.
I'm fairly new to C so be gentle.
I want to use the library interception method for Linux to replace calls to the OpenCL library with my own library. I understand that this can be done using LD_PRELOAD. So I can just re-implement the OpenCL functions as defined in the OpenCL header file within my own library which can then be linked against.
The problem is that this OpenCL header also contains some extern struct definitions, e.g.
typedef struct _cl_mem * cl_mem;
which are not defined within the OpenCL header. Is it possible these structs are defined within the OpenCL shared lib? If not, where might they be defined?
Cheers
Chris
That typedef declares a type pointing to a struct, the contents of which are undeclared. This means code using it can't do things like checking its size, copying the struct, or inspecting its contents - it simply has no idea what size it is.
This is a traditional technique in C to create an opaque, or private, type. You can declare the struct inside your OpenCL library, and the official header puts no restrictions on what that struct contains. It could even be empty, if all you need is an ID you can store in the pointer itself, though this is rarely done.
An example of the same technique used in the standard C library is the FILE type. It might be as simple as an integer file descriptor, or as complex as a struct containing the entire filesystem state; standard C code won't know. The particulars are known to the library only.
In short, you can declare that struct however you like - as long as you implement every function that handles that struct. The program that links to your library never handles the struct, only pointers to it.