will these lines do the same? If not, what's the difference? How do I decide where to put the asterisk?
#define OUT1 *((portptr ) SIGDATA_ADR)
#define OUT1 ((portptr *) SIGDATA_ADR)
Ok, sorry for the vague problem description.
What I'm trying to do is a function that continuously reads the value of two switches, makes a XOR, and puts it on a LED ramp.
My program looks like this; and it should work.
typedef unsigned char *port8ptr;
#define OUT *((port8ptr) 0x400)
#define IN1 *((port8ptr) 0x600)
#define IN2 *((port8ptr) 0x601)
void DipSwitchEor( void )
{
while( 1 )
{
OUT = IN1 ^ IN2;
}
}
So I'm just curious if I could have written #define OUT ((port8ptr *) 0x400) instead. I'm getting mixed answers.
There is a huge difference between these two macro definitions
#define OUT *((port8ptr) 0x400)
#define OUT ((port8ptr*) 0x400)
The first one first makes a port8ptr (cast) that points at memory address 0x400, then it dereferences this pointer (* operator outside of parentheses) to yield the unsigned char that is located at memory address 0x400.
The second one makes a pointer to a port8ptr that points at memory address 0x400. The result has the same type as a variable foo declared with port8ptr* foo;. That is, the result is a double pointer to an unsigned char, the char being located in memory wherever the pointer stored at memory address 0x400 is pointing at.
If all you need is to tell what various C declaration constructs mean, I think that you should try http://cdecl.org. It is also a utility that you can install on your computer. Probably what you want with your example is the code below, assuming that 0x600, 0x601 and 0x400 are the addresses of your registers:
void dip_switch() {
unsigned char *in1 = 0x600;
unsigned char *in2 = 0x601;
unsigned char *out = 0x400;
*out = (*in1) ^ (*in2);
}
Using #defines will only bite you in a situation like this. You should probably steer away from it.
The definitions of OUT1 and OUT2 are not semantically equivalent.
In the first case SIGDATA_ADR is cast to a pointer type portptr, and then dereferenced, so the argument to OUT1() in the first case is the data pointed to by SIGDATA_ADR. This makes sense and is likely the correct semantics - given you subsequent example of the use case, it is certainly correct.
In the second case, (portptr*) is a pointer-to-pointer, and the argument to OUT1() in the second case SIGDATA_ADR cast to a pointer-to-pointer - which seems unlikely.
Note that in the first case the * is the dereference operator, and the second it is not an operator but a data type modifier. They are not the same thing - they just happen to be represented by the same character - context is everything; understanding that probably makes determining which is correct far simpler.
Related
I'm dealing with pointers, double-pointers and arrays, and I think I'm messing up a bit my mind. I've been reading about it, but my particular user-case is messing me up, and I'd appreciate if someone could clear a bit my mind. This is a small piece of code I've built to show my misunderstanding:
#include <stdio.h>
#include <stdint.h>
void fnFindValue_vo(uint8_t *vF_pu8Msg, uint8_t vF_u8Length, uint8_t **vF_ppu8Match, uint8_t vF_u8Value)
{
for(int i=0; i<vF_u8Length; i++)
{
if(vF_u8Value == vF_pu8Msg[i])
{
*vF_ppu8Match = &vF_pu8Msg[i];
break;
}
}
}
int main()
{
uint8_t u8Array[]={0,0,0,1,2,4,8,16,32,64};
uint8_t *pu8Reference = &u8Array[3];
/*
* Purpose: Find the index of a value in u8Array from a reference
* Reference: First non-zero value
* Condition: using the function with those input arguments
*/
// WAY 1
uint8_t *pu8P2 = &u8Array[0];
uint8_t **ppu8P2 = &pu8P2;
fnFindValue_vo(u8Array,10,ppu8P2,16); // Should be diff=4
uint8_t u8Diff1 = *ppu8P2 - pu8Reference;
printf("Diff1: %u\n", u8Diff1);
// WAY 2
uint8_t* ppu8Pos; // Why this does not need to be initialized and ppu8P2 yes
fnFindValue_vo(u8Array,10,&ppu8Pos,64); // Should be diff=6
uint8_t u8Diff2 = ppu8Pos - pu8Reference;
printf("Diff2: %u\n", u8Diff2);
}
Suppose the function fnFindValue_vo and its arguments cannot be changed. So my purpose is to find the relative index of a value in the array taking as reference the first non-zero value (no need to find it, can be hard-coded).
In the first way, I've done it following my logic and understanding of the pointers. So I have *pu8P2 that contains the address of the first member of u8Array, and **ppu8P2 containing the address of pu8P2. So after calling the funcion, I just need to substract the pointers 'pointing' to u8Array to get the relative index.
Anyway, I tried another method. I just created a pointer, and passed it's address, without initializing the pointer, to the funcion. So later I just need to substract those two pointers and I get also the relative index.
My confusion comes with this second method.
Why ppu8Pos does not have to be initialized, and ppu8P2 yes? I.e. Why couldn't I declare it as uint8_t **ppu8P2;? (it gives me Segmentation fault).
Which of the two methods is more practical/better practice for coding?
Why is it possible to give the address to a pointer when the function's argument is a double pointer?
Why ppu8Pos does not have to be initialized, and ppu8P2 yes
You are not using the value of ppu8Pos right away. Instead, you pass its address to another function, where it gets assigned by-reference. On the other hand, ppu8P2 is the address of ppu8Pos you pass to another function, where its value is used, so you need to initialise it.
Which of the two methods is more practical/better practice for coding
They are identical for all intents and purposes, for exactly the same reason these two fragments are identical:
// 1
double t = sin(x)/cos(x);
// 2
double s = sin(x), c = cos(x);
double t = s/c;
In one case, you use a variable initialised to a value. In the other case, you use a value directly. The type of the value doesn't really matter. It could be a double, or a pointer, or a pointer to a pointer.
Why is it possible to give the address to a pointer when the function's argument is a double pointer?
These two things you mention, an address to a pointer and a double pointer, are one and the same thing. They are not two very similar things, or virtually indistinguishable, or any weak formulation like that. No, the two wordings mean exactly the same, to all digits after the decimal point.
The address of a pointer (like e.g. &pu8P2) is a pointer to a pointer.
The result of &pu8P2 is a pointer to the variable pu8P2.
And since pu8P2 is of the type uint8_t * then a pointer to such a type must be uint8_t **.
Regarding ppu8Pos, it doesn't need to be initialized, because that happens in the fnFindValue_vo function with the assignment *vF_ppu8Match = &vF_pu8Msg[i].
But there is a trap here: If the condition vF_u8Value == vF_pu8Msg[i] is never true then the assignment never happens and ppu8Pos will remain uninitialized. So that initialization of ppu8Pos is really needed after all.
The "practicality" of each solution is more an issue of personal opinion I believe, so I leave that unanswered.
For starters the function fnFindValue_vo can be a reason of undefined behavior because it does not set the pointer *vF_ppu8Match in case when the target value is not found in the array.
Also it is very strange that the size of the array is specified by an object of the type uint8_t. This does not make a sense.
The function should be declared at least the following way
void fnFindValue_vo( const uint8_t *vF_pu8Msg, size_t vF_u8Length, uint8_t **vF_ppu8Match, uint8_t vF_u8Value )
{
const uint8_t *p = vF_pu8Msg;
while ( p != vF_pu8Msg + vF_u8Length && *p != vF_u8Value ) ++p;
*vF_ppu8Match = ( uint8_t * )p;
}
The difference between the two approaches used in your question is that in the first code snippet if the target element will not be found then the pointer will still point to the first element of the array
uint8_t *pu8P2 = &u8Array[0];
And this expression
uint8_t u8Diff1 = *ppu8P2 - pu8Reference;
will yield some confusing positive value (due to the type uint8_t) because the difference *ppu8P2 - pu8Reference be negative.
In the second code snippet in this case you will get undefined behavior due to this statement
uint8_t u8Diff2 = ppu8Pos - pu8Reference;
because the pointer ppu8Pos was not initialized.
Honestly, not trying to understand your code completely, but my advice is do not overcomplicate it.
I would start with one fact which helped me untangle:
if you have int a[10]; then a is a pointer, in fact
int x = a[2] is exactly the same like int x = *(a+2) - you can try it.
So let's have
int a[10]; //this is an array
//a is a pointer to the begging of the array
a[2] is an int type and it is the third value in that array stored at memory location a plus size of two ints;
&a[2] is a pointer to that third value
*(a) is the first value in the array a
*(a+1) is the same as a[1] and it is the second int value in array a
and finally
**a is the same as *(*a) which means: *a is take the first int value in the array a (the same as above) and the second asterisk means "and take that int and pretend it is a pointer and take the value from the that location" - which is most likely a garbage.
https://stackoverflow.com/questions/42118190/dereferencing-a-double-pointer
Only when you have a[5][5]; then a[0] would be still a pointer to the first row and a[1] would be a pointer to the second row and **(a) would then be the same as a[0][0].
https://beginnersbook.com/2014/01/2d-arrays-in-c-example/
Drawing it on paper as suggested in comments helps, but what helped me a lot is to learn using debugger and break points. Put a breakpoint at the first line and then go trough the program step by step. In the "watches" put all variants like
pu8P2,&pu8P2,*pu8P2,**pu8P2 and see what is going on.
I'm trying to understand some sample C code that I got with my microcontroller board. I have a really hard time to understand that whole pointer thing. I read a lot of posts in this forum and I also read several tutorials and slowly I get the hang of it :) But...
In my sample code there is the following line of code, which I could not decrypt with any information that I have found yet.
#define SOMENAME ((uint32_t *)0x130010f0)
I understood, that #define simply replaces all occurrences of SOMENAME in the compiled code with the respective statement (don't know if this is correctly explained, but I really think I got what this is doing).
Now, what I could imagine, what the rest of the statement means is the following:
SOMENAME is now a pointer to the address 0x130010f0 but without being an actual variable.
Is this correct? And I could kind of use it for example as: printf("value at address 0x130010f0: %p",SOMENAME) because the compiler would replace it with printf("value at address 0x130010f0: %p",((uint32_t *)0x130010f0)) and this gives the value stored at that address? What would be the print statement if I want the address of that pointer? I can't, right? Because the pointer does not have an address as it is not a variable? Very confusing...
The example is quite complex and this definition is also part of other definitions which are pointers to structs of structs of structs, therefore this "simple" example. Below you can find the "whole" structure:
#define ROM_API_TREE ((uint32_t *)0x130010f0)
#define BOOTLOADER_POINTER ((bootloader_tree_t *)ROM_API_TREE)
flash_driver_interface_t *FLASH_API_TREE
#define FLASH_API_TREE BOOTLOADER_POINTER->flashDriver
typedef struct BootloaderTree{
...
const flash_driver_interface_t *flashDriver;
} bootloader_tree_t
typedef struct FlashDriverInterface{
...
status_t (*ffr_get_uuid)(flash_config_t *config, uint8_t *uuid);
} flash_driver_interface_t
/*
* I actually want to understand that statement, but as I fail
* already at the beginning, I posted this question
*/
status_t = FLASH_API_TREE->ffr_get_uuid(config,uuid);
You are correct that SOMENAME get replaced by the preprocessor with ((uint32_t *)0x130010f0). What this gives you is a pointer to a uint32_t, and the value of that pointer is 0x130010f0.
When you then do this:
printf("value at address 0x130010f0: %p",SOMENAME);
You'll actually print the value of the pointer, i.e. 0x130010f0, not what it points to. For that you would need to dereference it, i.e.:
printf("value at address 0x130010f0: %u", *SOMENAME);
This however assumes that 0x130010f0 is a valid address that can be dereferenced and read. This will typically only be the case in some particular embedded environment where the implementation allows it.
As i saw, you basically could understand many things behind the Pointers. The SOMENAME is a macro not a variable right. Before i get to the code, a pointer in general is nothing else but a variable that contains an adress instead of having a value.
printf("value at address 0x130010f0: %p",SOMENAME); is wrong because the %p expects a value not an Adress and you are passing the adress to it, so you all you have to do is to dereference it using the *.
When you write (uint32_t *)0x130010f0 you are casting the adress to the type writteb between parentheses.
Whenever it gets complicated while using pointers try to remember this small example:
int a = 10;
int *p = &a;// declare pointer of type integer. This is valid, adress of an integer variable contains adress of integer variable
int *j; //declare pointer of type integer
j = &a; //correct, because j expects an adress.
*j = &a; //wrong *j expects a value
printf("value of p: %p", *p);
printf("adress of p: %p", p); //or &p
This shows that your microcontroller board has a program accessible 32-bit device.
I say 'accessible' because this device could be readable, writable or both.
I use the kinda general term 'device' because it could be all kinds of things. Quite often it's a register that simply stores a value, but it could also be a FIFO chip returning the next stored value at every read.
Assuming it's a register: These registers often consist of separate bits or small groups of bits to represent some function. In that case you'd see bitfield struct declarations that look like this (two 16-bit fields as example):
struct {
uint32_t someField : 16;
uint32_t otherField : 16;
} fields;
I have read what I could find on pointers in C/C++ but most of it is introductory, and while it helps you to understand using them there are many cases where existing code throws examples that are troublesome to decipher.
I did see some examples where they break down a line of code into what it really means and some of the more complex ones end up with something like: "a pointer to a function that returns a pointer to a pointer of an int"
Ok great, but what kind of scenario would you run into where you would end up with this? Is this sort of pointer situation something that comes up often? It does not seem very readable and if you had code full of this I could see a great possibility of bugs popping up.
I have found one line of code in a library that I do not fully understand but it is not quite the crazy deciphered example listed above:
*(uint8_t *)&(SPI2->DR) = SPI2_DATA;
SPI2_DATA is getting assigned to the DR of SPI2, but what is all that other code for?
As far as I can tell the code is doing a bitwise AND between a pointer to a uint8_t and the DR of SPI2 and then dereferencing the whole thing to assign SPI2_DATA to it. I know that is not right though?
You should decompose the instruction to fully understand what happens:
*(uint8_t *)&(SPI2->DR) = SPI2_DATA
&SPI->DR obtains the address of the variable DR in struct/class SPI, this address has type Something* where Something is the type of DR.
Then this address is casted to uint8_t*, so it is casted to a pointer to a uint8_t, which is a fixed width unsigned integer of 1 byte.
Finally this address is dereferenced to assign SPI2_DATA to it.
Something like:
Something* temp1 = &SPI2->DR;
uint8_t* temp2 = (uint8_t*)temp1;
*temp2 = SPI2_DATA;
Here's an example of what it does:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#define SPI2_DATA 0xfc
struct spi {
uint16_t DR;
};
int main ( void ) {
struct spi * SPI2 = malloc(sizeof(*SPI2));
SPI2->DR = 0x3210; /* some initial value chosen on a whim */
printf("before: %04x\n", SPI2->DR);
*(uint8_t *)&(SPI2->DR) = SPI2_DATA;
printf(" after: %04x\n", SPI2->DR);
return 0;
}
before: 3210
after: 32fc
Note how only 8 bits of the value changed.
SPI2->DR is probably declared as a pointer, but not a pointer to the type uint8_t (maybe it's declared as a pointer to void). SPI2_DATA is of type uint8_t. So in order to copy SPI2_DATA into the target of SPI2->DR, the code is getting the pointer using &, converting the pointer to the correct type with a cast, then dereferencing it.
I looked at
http://www.opensource.apple.com/source/xnu/xnu-2050.24.15/libsyscall/wrappers/memcpy.c
and didn't understand the following :
1-
inside
void * memcpy(void *dst0, const void *src0, size_t length) {
char *dst = dst0;
const char *src = src0;
line:
if ((unsigned long)dst < (unsigned long)src) {
How can we cast dst to an unsigned long ? it's a pointer !
2- Why do they sometimes prefer forward copying and sometimes backwards??
You are right, this implementation is non-portable, because it is assuming that a pointer is going to fit in unsigned long. This is not guaranteed by the standard.
A proper type for this implementation would have been uintptr_t, which is guaranteed to fit a pointer.
When comparing a void* and char* pointer, the compiler will give a warning (gcc -Wall):
warning: comparison of distinct pointer types lacks a cast
I imagine that the developer decided to "make the warning go away" - but the correct way to do this is with a void* cast (which is portable):
if((void*) dst < (void*) src) {
As for the second point - as was pointed out, you have to take care of overlapping memory locations. Imagine the following 8 characters in successive memory locations:
abcdefgh
Now we want to copy this "3 to the right". Starting with a, we would get (with left-to-right copy):
abcdefgh
abcaefgh
^
abcabfgh
^^
abcabcgh
^^^
etc until you end up with
abcabcabcab
^^^^^^^^
When we wanted to get
abcabcdefgh
Starting from the other end, we don't overwrite things we still have to copy. When the destination is to the left of the source, you have to do it in the opposite direction. And when there is no overlap between source and destination, it doesn't matter what you do.
I'm doing programming of a softcore processor, Nios II from Altera, below is the code in one of the tutorial, I manage to get the code working by testing it on the hardware (DE2 board), however, I could not understand the code.
#define Switches (volatile char *) 0x0003000
#define LEDs (char *) 0x0003010
void main()
{ while (1)
*LEDs = *Switches;
}
What I know about #define is that, it is either used to define a constant, or a macro, but
why in the above code, there are casting like, (char *) 0x0003010, in #define?
why the 2 constants, Switches and LEDs act like a variable instead of a constant?
1) why in the above code, there are casting like, (char *) 0x0003010, in #define?
Preprocessor macros are textual replacements. So the code comes out as
while (1) {
*(char *) 0x0003010 = *(volatile char *) 0x0003000
}
which repeated assigns the contents of the input (switch) mapped at 0x3000 to the output (led) mapped at 0x3010.
2) why the 2 constants, Switches and LEDs act like a variable instead of a constant?
Note that those are pointer. So they always point to the same place (which happens to be a couple of memory mapped IO pins or something similar), but there is no guarantee the the contents of those constant locations are constant, and the * appearing before each preprocessor symbol is the pointer de-reference operator.
It appears that Switches and LEDs represent the memory-mapping to the actual input (in the case of Switches) and output (in the case of LEDs).
So your answers include:
The byte for the input switches is memory-mapped to address 0x0003000. In order to access that as a byte, you need to tell the compiler that whatever is at address 0x0003000 is a char (in fact, you tell it that the value at that address is a volatile char, so that the compiler doesn't optimize away the fact that the value at that address may change at any time).
They are constants, but they are constant pointers. That is to say, the address is constant, but the values contained at those addresses are not constant.
What happens is that every clock cycle (or so), whatever is read from memory address 0x0003000 is then written to address 0x0003010. This gives the illusion that the switches instantly toggle the LEDs.
In C, macros are simple substitutions.
Every time the compiler sees LEDs in your code it will replace it with (char *) 0x0003010.
So your code is effectively the same as this:
void main()
{
while (1)
*(char *) 0x0003010 = *(volatile char *) 0x0003000;
}
Without the type casting at the #defines, they wouldn't be treated as char* and volatile char*. What is at *Switches is copied into *LEDs.