In C++, we have the keyword alignas(n) and we have the _aligned_malloc(m,n) function.
alignas works on the type while aligned_malloc works on whatever you call it.
Can I use alignas(16) to fullfil the 16-byte alignment requirement for Direct3D Constant Buffers?
Yes, you could use it like this:
struct SceneConstantBuffer
{
alignas(16) DirectX::XMFLOAT4X4 ViewProjection[2];
alignas(16) DirectX::XMFLOAT4 EyePosition[2];
alignas(16) DirectX::XMFLOAT3 LightDirection{};
alignas(16) DirectX::XMFLOAT3 LightDiffuseColor{};
alignas(16) int NumSpecularMipLevels{ 1 };
};
What won't work is __declspec(align)...
EDIT: If you want to use it on the struct itself something similar to this should work too:
struct alignas(16) SceneConstantBuffer
{
DirectX::XMMATRIX ViewProjection; // 16-bytes
...
DirectX::XMFLOAT3 LightDiffuseColor{};
}
Related
Why is it that in the source code in the SDK for LPNMITEMACTIVATE it is defined with the asterix to the left?
typedef struct tagNMITEMACTIVATE
{
NMHDR hdr;
int iItem;
int iSubItem;
UINT uNewState;
UINT uOldState;
UINT uChanged;
POINT ptAction;
LPARAM lParam;
UINT uKeyFlags;
} NMITEMACTIVATE, *LPNMITEMACTIVATE;
I am always used to the pointer being on the right. Either way, code like:
const LPNMITEMACTIVATE pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
Will still flag a const (C26462) warning:
If I change the code to:
const NMITEMACTIVATE* pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
The warning will go away.
I tried this with Visual Studio 2022, first of all, warning C26462 was not enabled by default. Perhaps you are using an earlier release, or there is something odd with my installation.
After manually enabling the warning, I could make that warning go away by assigning pNMItem more than once:
LPNMITEMACTIVATE pNMItem = nullptr;
pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
How is this useful?
Or it can be fixed as suggested in other answers. But you may have additional problem because pNMHDR was probably declared as LPNMHDR, so you have to rewrite more lines:
NMHDR hdr = { 0 };
const NMHDR* pNMHDR = reinterpret_cast<NMHDR*>(&hdr);
const NMITEMACTIVATE* pNMItem = reinterpret_cast<const NMITEMACTIVATE*>(pNMHDR);
This can be a big waste of time. Note, the extra compliance is recommended if you are writing code that's supposed to run on any system. But MFC is tied to Windows so this isn't really an issue. MFC and Windows are still using that "long pointer" crap that's left over from 16-bit Windows, they are not compliant themselves, so consider turning off some of these warnings.
This is standard C/C++
Like in this (not runnable) code snippet:
typedef int *LPINT;
// typedef int* LPINT; // you could write this, it's exactly the
// the same as above
int main()
{
LPINT pint;
int* pint2;
*pint = *pint2;
}
pint and pint2 are both pointers to int. BTW this is hiding a pointer type behind a typedef, which is a bad idea (but was considered as a good idea in old MS days), but lots of Microsoft headers still have these typedef sometype *LPsometype; typedefs for compatibility reasons.
Another example which is closer to the MS header you're refering to:
This:
typedef struct tagNMITEMACTIVATE
{
int hdr;
int iItem;
} NMITEMACTIVATE, *LPNMITEMACTIVATE;
is equivalent to this:
typedef struct tagNMITEMACTIVATE
{
int hdr;
int iItem;
} NMITEMACTIVATE;
typedef struct tagNMITEMACTIVATE *LPNMITEMACTIVATE;
For pointer const can be applied to the type the pointer points at:
const NMITEMACTIVATE* p;
or
NMITEMACTIVATE const* p;
Or it can be applied to the pointer variable itself:
NMITEMACTIVATE* const p;
Now if you have typedef:
typedef NMITEMACTIVATE *PNMITEMACTIVATE;
The const would not apply to the type being pointed at. Either way it is the pointer itself is constant:
const PNMITEMACTIVATE p;
PNMITEMACTIVATE const p;
To avoid this confusion, prefer not to use raw pointer typedefs (and not to define them).
Is it possible to EXPORT_SYMBOL() a struct that contains a kmalloc array? If yes, what are the things that I need to keep in mind?
This is a psuedo code of what I want to do.
struct test {
int a;
...
uint64_t* data;
}
struct test foo;
EXPORT_SYMBOL(foo);
...
In module1_kthread1_func() I have:
int module1_kthread1_func(void *foo){
...
foo->data = kmalloc(SIZE, GFP_KERNEL);
...
foo->data[var] = 1243;
var++;
...
}
In module2_kthread2_func() I have:
...
extern struct test foo;
...
int module2_kthread2_func(void* foo){
...
for (i=0; i<SIZE; i++)
printk(KERN_INFO "Variable value of %d is %llu", i, foo->data[var]);
...
}
It's definitely possible, yes.
You need to be careful and make sure that code that uses it knows that some of the fields might not be available before they are allocated. That is, check if they are NULL first instead of directly accessing them.
You might want to declare the structure with an explicit initializer, just so that it is obvious what is going on:
struct test foo = {
.a = 123,
.data = NULL // Initialized by function X when Y
};
EXPORT_SYMBOL(foo);
If such fields are compulsory for the structure to be used, you might want to initialize them early on (see here).
I would have posted this in the spinroot Bug Reports, but the spinroot forum is not currently accepting new users... If someone out there in charge of that is reading this, please let me in :)
Something very odd is happening when I try to use the select statement. Promela does not allow select() to be called on the field of a struct, so I have to make a temporary variable like this:
typedef someStruct {
int someField;
}
someStruct struct;
inline SetSelect() {
int temp;
select(temp: -1 .. 1);
struct.someField = temp;
}
init{
SetSelect();
}
This runs fine. I tested it and struct.someField is correctly set to either -1, 0, or 1. However, when I try to just put the inlined code straight into the init() process, I get a syntax error. The code looks like this:
typedef someStruct {
int someField;
}
someStruct struct;
init{
int temp;
select(temp: -1 .. 1);
struct.someField = temp;
}
And the error message is:
spin: select_test.pml:9, Error: syntax error saw ''-' = 45'
BUG:
Indeed, it looks like a bug for version 6.4.6 of Spin.
(The bug is fixed in version 6.4.7)
Interestingly, You can make it go away by simply writing temp : instead of temp:.
I suggest you to contact Gerard Holzmann for filing a bug report. I would also mention the fact that select does not seem to work with a struct field, perhaps that can be fixed too (even if it might be by design).
SUGGESTION:
I am not entirely happy of creating an alias variable to get around the issue of the built-in select function with struct fields. Since the implementation of select is rather trivial, as can be found in the docs, I would introduce a novel inline function to replace the built-in select function:
typedef Struct
{
int field;
}
inline my_select (var, lower, upper)
{
var = lower;
do
:: var < upper -> var++;
:: break;
od;
}
init
{
Struct st;
my_select(st.field, -1, 1);
printf("%d\n", st.field);
}
I'm having trouble with declaration and initialization of a struct in Vectors CANoe CAPL. I already know structs from C/C++ but it seems the declaration is a little different in CAPL.
The Vector help function isn't really revealing.
I have a number of CAN IDs (e.g. 0x61A). Every CAN ID is a different number of Signal IDs (e.g. 0xDDF6) assigned. I want to read out cyclic the Signal ID from the CAN IDs and plan to organize this in a convoluted struct.
I already tried out different types of declaration and initialization but every time I get a parse error.
Can you please give me a helping hand for my problem?
Any other ideas to organize my values unlike a struct?
Thank you and regards!
From the CAPL documentation:
Structured types can be declared in CAPL in a similar way to C...
... they may only be used in CAPL programs with CANoe from version 7.0 Service Pack 3.
Example:
variables
{
/* declarating a struct */
struct MyData {
int i;
float f;
};
}
on start
{
/* defining a struct variable and initiliazing the elements */
struct MyData data = {
i = 42,
f = 1.32
};
/* accessing the struct elements */
write("i=%d, f=%f", data.i, data.f);
}
Output:
i=42, f=1.320000
I had a flaw in struct access. Tried to initialize the struct paramters right in the variable declaration routine, not in the on startroutine.
Working code for my multiple data access is now:
variables
{
struct Veh_Database
{
dword ECU;
dword ParamID[8][2];
};
struct Veh_Database ECU_Info[12];
}
on start
{
ECU_Info[0].ECU = 0x1A;
ECU_Info[0].ParamID[0][0] = 0xDD;
ECU_Info[0].ParamID[0][1] = 0xF6;
/* ... */
ECU_Info[1].ECU = 0x12;
ECU_Info[1].ParamID[0][0] = 0xDE;
ECU_Info[1].ParamID[0][1] = 0x9C;
/* ... */
}
Thanks for your help!
Just for completeness: It is also possible to initialize a struct in the variable declaration:
variables
{
struct myStruct
{
dword val;
dword arr[8];
};
struct myStruct myInstance = {1, {1,2,3,4,5,6,7,8}};
}
(tested on CANoe 10)
CAPL allows initialization of variables structures at declaration also at Onstart procedure but we have to follow correct syntax. here is example code
variables
{
struct mydata
{
int a;
int b;
} ak={5,3};
}
on start
{
write("Initial values are %d, %d",ak.a,ak.b);
ak.a=10;
ak.b=20;
write("values after update are %d, %d", ak.a,ak.b);
}
find more details in following video
https://www.youtube.com/watch?v=hRfSqZBZVHA
For various (C++11 std::string-change-related) reasons I would like to use a non-std::string string class in some places in my C++11-ish code, which need to be agreeable with several versions of several C++ compilers.
Now, I don't really mind whether my strings behave in pre-C++11-style or post-C++11 way; and I don't care about performance either. I just want a nice reliable string class which under no circumstances gives me errors involving std::__cxx11::string and other such voodoo.
What are my options? Can I/should I replicate some single compiler's implementation in my own header files? Is GCC's vstring an option? Something else?
template<class T>
struct crappy_string {
mutable std::vector<T> buffer;
T const* c_str() const {
if (buffer.empty() || buffer.back())
buffer.push_back(0);
return buffer.data();
}
friend bool operator<( crappy_string const& lhs, crappy_string const& rhs ) {
lhs.c_str(); rhs.c_str(); // ensure null terminator in both
return lhs.buffer < rhs.buffer;
}
};
This satisfies the minimal requirements you gave in the comments.