I have a C class that works like the Linux "devmem" utility for embedded systems. I'll simplify and give an outline of it here:
struct DevMem
{
DevMem(off_t start, off_t end)
{
// map addresses start to end into memory with mmap
}
~DevMem()
{
// release mapped memory with munmap
}
uint32_t read(off_t address)
{
// return the value at mapped address
}
void write(off_t address, uint32_t value)
{
// write value to mapped address
}
};
I use it like this:
void WriteConverter(uint32_t value)
{
off_t base = 0xa0000000;
DevMem dm(base, base 0x100); // set up mapping for region
dm.write(base 0x8, value); // output value to converter
dm.write(base 0x0, 1); // strobe hardware
while (dm.read(base 0x4)) // wait until done
;
}
And this works great. RAII ensures the mapped memory is released when I'm done with it. But some hardware is really simple and only needs a single read or write. It was bothering me that in order to access that hardware, I would have to invent some name for the instantiation of the class:
DevMem whatever(0xa0001000, 0xa0001000); // map the thing
whatever.write(0xa0001000, 42); // do the thing
With the named object and the repetition of the address three times, it's a little verbose. So I made a change to the constructor so that I could leave off the end parameter if I'm only mapping a single address:
DevMem(off_t start, off_t end = 0)
{
// map addresses start to end into memory with mmap
}
And then I overloaded the read and write routines so the address wasn't passed:
uint32_t read()
{
// return the value at the constructor's start address
}
void write(uint32_t value)
{
// write value to the constructor's start address
}
And I discovered that I could then do this:
DevMem(0xa0001000).write(42); // do the thing
And this works. I don't need to invent a name for the object, it's less verbose, the value is written (or read), and RAII cleans it up nicely. What I assume is happening is that C is constructing an unnamed object, dereferencing it, using it, and then destructing it.
Is this use of an unnamed object valid? I mean, it compiles okay, GCC and clang don't complain with common warnings cranked up, and it does actually work on the target hardware. I just can't find any examples of such a thing on the Interwebs. Is this a named idiom?
CodePudding user response:
Yep, completely valid. You create the object, use it and then the destructor kicks in. Your compiler will probably generate the same assembly in your whatever
example if whateverhas
a reasonable scope.
I don't know any names for this construct though. As well as I wouldn't call this an idiom.