qt QFlags: signed value is out of range for enum constant - c++

I got following warnings for the enum value xxxxx920P4 building a qt C++ project. And I found out in the debugging that xxxxx920P4 is now equals to xxxxxundefine (0x00000000), which causes the unexpected result. How should I resolve this problem?
I'm using Qt version: 4.8.7 and Visual studio 2010.
The following loop will not be executed. gVersions[0].verNum is "xxxxx920P4", so I guess "xxxxx920P4"'s value has been truncated and now it equals to 0x00000000.
for(int i=0; gVersions[i].verNum != xxxxxundefine ; i++)
{
}
Doc for Qt Qflags class: https://doc.qt.io/qt-5/qflags.html
warning C4341: 'xxxxx920P4' : signed value is out of range for enum constant
warning C4309: 'initializing' : truncation of constant value
enum Version
{
xxxxxundefine = 0x00000000,
xxxxx400 = 0x00000001,
xxxxx401 = 0x00000002,
xxxxx410 = 0x00000004,
xxxxx411 = 0x00000008,
xxxxx412 = 0x00000010,
xxxxx420 = 0x00000020,
xxxxx430 = 0x00000040,
xxxxx431 = 0x00000080,
xxxxx432 = 0x00000100,
xxxxx440 = 0x00000200,
xxxxx500 = 0x00000400,
xxxxx510 = 0x00000800,
xxxxx520 = 0x00001000,
xxxxx521 = 0x00002000,
xxxxx600 = 0x00004000,
xxxxx611 = 0x00008000,
xxxxx620 = 0x00010000,
xxxxx621 = 0x00020000,
xxxxx700 = 0x00040000,
xxxxx910 = 0x00080000,
xxxxx910P5 = 0x00100000,
xxxxx910P6 = 0x00200000,
xxxxx910P11 = 0x00400000,
xxxxx910P12 = 0x00800000,
xxxxx910P13 = 0x01000000,
xxxxx910P14 = 0x02000000,
xxxxx910P15 = 0x04000000,
xxxxx910P16 = 0x08000000,
xxxxx920 = 0x10000000,
xxxxx920P1 = 0x20000000,
xxxxx920P2 = 0x40000000,
xxxxx920P3 = 0x80000000,
xxxxx920P4 = 0x100000000,
}; Q_DECLARE_FLAGS(Versions, Version)

The last value is too long to fit into a a non-long int. While newer compilers may try to choose a larger integral type for it, some older ones would complain. GCC tends to do the former unless you choose type explicitly. Note that second to last value 0x80000000 or any combination of masks involving it would not fit into int, it's essentially a negative -2147483648.
enum Version : long long
{
//...
xxxxx920P4 = 0x100000000,
};
PS. Apparently Qt5 doesn't support something different from (unsigned)int: https://doc.qt.io/qt-5/qflags.html

Related

Custom Scalar Value Types

I am currently trying to rewrite the network code of a MFC application to fit it to a new server, (written in c#) later on.
I'm experimenting with protobuf to ensure that all data models are the same.
My problem is, that the Scalar Value Types, protobuf works with is not understood by the MFC type system. It uses DWORD instead of uint32, BYTE instead of byte or bool and so on. That requires custom type mapping/casting and that's not necessarily taking work from my shoulders.
Is there a way to change those datatypes used in protobuf?
A sample protobuf model would be:
syntax = "proto3";
package CInterop;
option csharp_namespace = "CCX.Protobuf.Login";
message LoginAck {
LoginResultStatus Status = 1;
uint32 dwUserID = 2;
uint32 dwCharID = 3;
uint32 dwKEY = 4;
uint32 dwMapIP = 5;
uint32 wPort = 6;
uint32 bCharCreateCount = 7;
bool IsInPcRoom = 8;
uint32 PremiumPcRoomValue = 9;
uint64 dCurrentTime = 10;
uint64 dKey = 11;
string Reason = 12;
uint64 iDuration = 13;
bool bEternal = 14;
}
The current usage would be
CInterop::LoginAck loginAck;
(*pPacket) >> loginAck; // Reads the packet from the buffer
m_dwUserID = (DWORD)loginAck.dwuserid();
m_dwKickID = (DWORD)loginAck.dwcharid();
m_dwKEY = (DWORD)loginAck.dwkey();
vADDR.sin_addr.S_un.S_addr = (ULONG)loginAck.dwmapip();
vADDR.sin_port = (USHORT)loginAck.wport();
m_bCreateCardCnt = (byte)loginAck.bcharcreatecount();
m_bInPCROOM = (BYTE)loginAck.isinpcroom();
m_dwPrmPCROOM = (DWORD)loginAck.premiumpcroomvalue();
But here, i don't want to cast the types, this should happen automatically somehow.

Vulkan timeline semaphore extension cannot be enabled

I've been at this for a better part of today and I'm at the end of my wits.
I'm running Vulkan SDK 1.2.131.2
I have a RTX 2080 Ti.
I have Windows 10 Education, version 1909, build 18363.657.
I'm using Vulkan.hpp instead of Vulkan.h directly.
Here is where I specify the API version I use:
appInfo.apiVersion = VK_API_VERSION_1_2;
This is the relevant part of the code that creates the device:
// bla bla
const std::vector<const char*> deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
VK_NV_RAY_TRACING_EXTENSION_NAME
};
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
m_logicalDevice = m_physicalDevice.createDeviceUnique(deviceCreateInfo);
I use the following validation layers:
"VK_LAYER_LUNARG_api_dump"
"VK_LAYER_KHRONOS_validation"
This is how I later try to create a timeline semaphore:
vk::UniqueSemaphore VulkanContext::createTimelineSemaphore(const uint32_t initialValue) const {
vk::SemaphoreTypeCreateInfo timelineCreateInfo;
timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
timelineCreateInfo.initialValue = initialValue;
vk::SemaphoreCreateInfo createInfo;
createInfo.pNext = &timelineCreateInfo;
return m_logicalDevice->createSemaphoreUnique(createInfo);
}
I get the following error:
vkCreateSemaphore(device, pCreateInfo, pAllocator, pSemaphore) returns VkResultVkCreateSemaphore: timelineSemaphore feature is not enabled, can not create timeline semaphores The Vulkan spec states: If the timelineSemaphore feature is not enabled, semaphoreType must not equal VK_SEMAPHORE_TYPE_TIMELINE (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSemaphoreTypeCreateInfo-timelineSemaphore-03252)
This is even more infuriating because timeline semaphores are supposed to be part of the core Vulkan 1.2, but I get the same error even if I ommit it from the extension list. Swapchain extension does work and I haven't had the time to verify that ray tracing extension is enabled.
It gets even more stupid because the next message tells me this:
VK_SUCCESS (0):
device: VkDevice = 0000023AA29BD8B0
pCreateInfo: const VkSemaphoreCreateInfo* = 0000008D145ED538:
sType: VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO (9)
pNext: VkSemaphoreTypeCreateInfo = 0000008D145ED4F8:
sType: VkStructureType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO (1000207002)
pNext: const void* = NULL
semaphoreType: VkSemaphoreType = VK_SEMAPHORE_TYPE_TIMELINE (1)
initialValue: uint64_t = 0
flags: VkSemaphoreCreateFlags = 0
pAllocator: const VkAllocationCallbacks* = NULL
pSemaphore: VkSemaphore* = AA989B000000001E
I have no idea if this creates the timeline semaphore or just creates a normal binary one.
When I later use it to submit to a transfer queue:
vk::CommandBufferBeginInfo beginInfo;
transferCmdBuffer->begin(beginInfo);
object->recordUploadToGPU(*transferCmdBuffer);
transferCmdBuffer->end();
vk::TimelineSemaphoreSubmitInfo timelineSubmitInfo;
timelineSubmitInfo.signalSemaphoreValueCount = 1;
timelineSubmitInfo.pSignalSemaphoreValues = &signalValue;
vk::SubmitInfo submitInfo;
submitInfo.pNext = &timelineSubmitInfo;
submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = &signalSemaphore;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &*transferCmdBuffer;
vkCtx.m_transferQueue.submit(submitInfo, nullptr);
I get this error here:
vkQueueSubmit(queue, submitCount, pSubmits, fence) returns VkResultVkQueueSubmit: VkQueue 0x23aa2539500[] contains timeline sempahore VkSemaphore 0xaa989b000000001e[] that sets its wait value with a margin greater than maxTimelineSemaphoreValueDifference The Vulkan spec states: For each element of pSignalSemaphores created with a VkSemaphoreType of VK_SEMAPHORE_TYPE_TIMELINE the corresponding element of VkTimelineSemaphoreSubmitInfo::pSignalSemaphoreValues must have a value which does not differ from the current value of the semaphore or the value of any outstanding semaphore wait or signal operation on that semaphore by more than maxTimelineSemaphoreValueDifference. (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkSubmitInfo-pSignalSemaphores-03244)
And just to be futher mocked, this is the next line:
VK_SUCCESS (0):
queue: VkQueue = 0000023AA2539500
submitCount: uint32_t = 1
pSubmits: const VkSubmitInfo* = 0000008D145ED370
pSubmits[0]: const VkSubmitInfo = 0000008D145ED370:
sType: VkStructureType = VK_STRUCTURE_TYPE_SUBMIT_INFO (4)
pNext: VkTimelineSemaphoreSubmitInfo = 0000008D145ED318:
sType: VkStructureType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO (1000207003)
pNext: const void* = NULL
waitSemaphoreValueCount: uint32_t = 0
pWaitSemaphoreValues: const uint64_t* = NULL
signalSemaphoreValueCount: uint32_t = 1
pSignalSemaphoreValues: const uint64_t* = 0000008D145ED740
pSignalSemaphoreValues[0]: const uint64_t = 1
waitSemaphoreCount: uint32_t = 0
pWaitSemaphores: const VkSemaphore* = NULL
pWaitDstStageMask: const VkPipelineStageFlags* = NULL
commandBufferCount: uint32_t = 1
pCommandBuffers: const VkCommandBuffer* = 0000008D145EF408
pCommandBuffers[0]: const VkCommandBuffer = 0000023AA9CEC8E0
signalSemaphoreCount: uint32_t = 1
pSignalSemaphores: const VkSemaphore* = 0000008D145EF430
pSignalSemaphores[0]: const VkSemaphore = AA989B000000001E
fence: VkFence = 0000000000000000
I've also tried with VK_API_VERSION_1_1 and VK_API_VERSION_1_0, both with and without enabling the extension explicitly, none of them work.
The dumps are from the VK_LAYER_LUNARG_api_dump validation layer, while VK_LAYER_KHRONOS_validation validation layer is the one spewing out the errors. They seem to disagree.
So, what gives?
In what way am I stupid today?
EDIT:
Here is an example that you should be able to run yourself. I think I made it as minimal as I can:
#include <vulkan/vulkan.hpp>
#include <iostream>
VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData) {
std::cerr << pCallbackData->pMessage << std::endl;
return VK_FALSE;
};
int main() {
vk::ApplicationInfo appInfo;
appInfo.apiVersion = VK_API_VERSION_1_2;
vk::InstanceCreateInfo instanceCreateInfo;
instanceCreateInfo.pApplicationInfo = &appInfo;
std::vector<const char*> extensions;
extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
instanceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
instanceCreateInfo.ppEnabledExtensionNames = extensions.data();
const std::vector<const char*> validationLayers = {
"VK_LAYER_LUNARG_api_dump",
"VK_LAYER_KHRONOS_validation"
};
instanceCreateInfo.enabledLayerCount = static_cast<uint32_t>(validationLayers.size());
instanceCreateInfo.ppEnabledLayerNames = validationLayers.data();
vk::DebugUtilsMessengerCreateInfoEXT debugCreateInfo;
debugCreateInfo.messageSeverity =
vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning |
vk::DebugUtilsMessageSeverityFlagBitsEXT::eError;
debugCreateInfo.messageType =
vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral |
vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation |
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance;
debugCreateInfo.pfnUserCallback = debugCallback;
instanceCreateInfo.pNext = &debugCreateInfo;
vk::Instance m_instance = vk::createInstance(instanceCreateInfo);
vk::DispatchLoaderDynamic m_loader = vk::DispatchLoaderDynamic(m_instance, vkGetInstanceProcAddr);
vk::DebugUtilsMessengerEXT m_debugMessenger = m_instance.createDebugUtilsMessengerEXT(debugCreateInfo, nullptr, m_loader);
vk::PhysicalDevice m_physicalDevice = m_instance.enumeratePhysicalDevices()[0];
std::vector<vk::DeviceQueueCreateInfo> queueCreateInfos;
vk::DeviceQueueCreateInfo queueInfo;
queueInfo.queueFamilyIndex = 0;
queueInfo.queueCount = 1;
queueCreateInfos.push_back(queueInfo);
vk::PhysicalDeviceFeatures deviceFeatures;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pQueueCreateInfos = queueCreateInfos.data();
deviceCreateInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
deviceCreateInfo.pEnabledFeatures = &deviceFeatures;
// This part can be omitted from here...
const std::vector<const char*> deviceExtensions = {
VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME
};
deviceCreateInfo.enabledExtensionCount = static_cast<uint32_t>(deviceExtensions.size());
deviceCreateInfo.ppEnabledExtensionNames = deviceExtensions.data();
// ...to here. It doesn't work either way.
vk::Device m_logicalDevice = m_physicalDevice.createDevice(deviceCreateInfo);
vk::SemaphoreTypeCreateInfo timelineCreateInfo;
timelineCreateInfo.semaphoreType = vk::SemaphoreType::eTimeline;
timelineCreateInfo.initialValue = 0;
vk::SemaphoreCreateInfo semaphoreCreateInfo;
semaphoreCreateInfo.pNext = &timelineCreateInfo;
m_logicalDevice.createSemaphore(semaphoreCreateInfo);
}
The feature needs to be enabled explicitly as well:
vk::PhysicalDeviceVulkan12Features features;
features.timelineSemaphore = true;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.pNext = &features;

vkCreateImage returns VK_ERROR_INITIALIZATION_FAILED although supported

My Vulkan implementation returns VK_ERROR_INITIALIZATION_FAILED whenever i call vkCreateImage. I checked output of vkGetPhysicalDeviceImageFormatProperties as well as output of vkGetPhysicalDeviceFormatProperties and made sure that format of the image i'm creating (with regard to it's creation parameters) is supported.
I've successfully initialized a Vulkan instance and a logical device, so the problem must lie somewhere else.
The Vulkan Spec mentions no VK_ERROR_INITIALIZATION_FAILED as a possible return value from vkCreateImage, which makes it more hard to uproot the problem.
The VkImageCreateInfo structure i push to vkCreateImage is as follows:
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.pNext = nullptr;
imageCreateInfo.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_UNORM;
imageCreateInfo.extent.width = 1024;
imageCreateInfo.extent.height = 1024;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
imageCreateInfo.mipLevels = 0;
imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.queueFamilyIndexCount = 0;
imageCreateInfo.pQueueFamilyIndices = nullptr;
As described in the specification:
mipLevels must be greater than 0
So judging by Your code, providing 0 value for number of mip levels may be the reason (or one of the reasons) of failure.

Assigning to [custom typdef] from incompatible type 'int'

In a method in my main.c file, I declare the variable irq_raised, which is of the type irq_type. I've defined irq_type in a typedef in another file and #import it at the top of main.c.
typedef enum
{
IRQ_NONE = 0x0000,
IRQ_VBLANK = 0x0001,
IRQ_HBLANK = 0x0002,
IRQ_VCOUNT = 0x0004,
IRQ_TIMER0 = 0x0008,
IRQ_TIMER1 = 0x0010,
IRQ_TIMER2 = 0x0020,
IRQ_TIMER3 = 0x0040,
IRQ_SERIAL = 0x0080,
IRQ_DMA0 = 0x0100,
IRQ_DMA1 = 0x0200,
IRQ_DMA2 = 0x0400,
IRQ_DMA3 = 0x0800,
IRQ_KEYPAD = 0x1000,
IRQ_GAMEPAK = 0x2000,
} irq_type;
I can assign this variable to one of these like so:
irq_raised = IRQ_NONE;
However, when I attempt to do the following:
irq_raised |= IRQ_HBLANK;
I get the error:
Assigning to 'irq_type' from incompatible type 'int'
Why is this?
In C++ you cannot assign an int directly to an enumerated value without a cast. The bitwise OR operation you are performing results in an int, which you then attempt to assign to a variable of type irq_type without a cast. It is the same problem as you would have here:
irq_type irq = 0; // error
You can cast the result instead:
irq_type irq = IRQ_NONE;
irq = (irq_type)(irq | IRQ_HBLANK);
Relevant info from the specification:
An enumerator can be promoted to an integer value. However, converting an integer to an enumerator requires an explicit cast, and the results are not defined.

Bitwise setting in C++

enum AccessSource
{
AccessSourceNull = 0x00000001,
AccessSourceSec = 0x00000002,
AccessSourceIpo = 0x00000004,
AccessSourceSSA = 0x00000008,
AccessSourceUpgrade = 0x00000010,
AccessSourceDelta = 0x00000020,
AccessSourcePhoneM = 0x00000040,
AccessSourceSoft = 0x00000080,
AccessSourceCR = 0x00000100,
AccessSourceA = 0x00000200,
AccessSourceE = 0x00000400,
AccessSourceAll = 0xFFFFFFFF
};
What is the value of AccessSourceAll ?? is it -1? or is it maximum value?
I have a parameter ULONG x , whose default value is AccessSourceAll(that means access to all). How do i remove the access right of AccessSourceE only?
How to add the access right of AccessSourceE again?
If i have a particular value in x, then how do i know whether AccessSourceE is set or not?
The value of AccessSourceAll is (int)0xFFFFFFFF since enum is of type int in C.
The unset just AccessSourceE use:
x & ~AccessSourceE // to assign: x &= ~AccessSourceE;
To add, use
x | AccessSourceE // to assign: x |= AccessSourceE;
To test,
if (x & AccessSourceE) { ... }
I'm not sure it'll actually matter since it is a mask which will clearly have a bit set for each of the other values.
If you are assigning it to a ULONG, it will be an unsigned type. To set/remove values use bitwise logic:
x |= AccessSourceE; /* set SourceE */
x &= ~AccessSourceE; /* unset SourceE */
if(x & AccessSourceE) /* test SourceE */
You can use the ^ operator for this.
For Example :
unsigned long l_unValue = AccessSource::AccessSourceAll;
l_unValue = l_unValue ^ AccessSource::AccessSourceE;
The above statement will remove "AccessSourceE" from "AccessSourceAll".