I read in data from an XML file, depending on the tags in the xml file, data gets attached to class member variables.
Is it possible if for example a value in the xml file contains "!", which in this case is not valid thus I can't accept that value.
So the member variable for that value is empty.
But the type of some member variables are other classes or integers or boolean. How can I check if those values are set? As there is no function emtpy() for those.
If they are not optional, you must cause your parsing mechanism to error when they are not present. Else, you could use something like boost::optional.
There is no way to detect at run time, whether a variable has been explicitly set. That's why some compilers give you a warning (not an error), if they suspect that a variable might be used uninitialized.
It is the programmer's responsibility, to keep track of what variables have been set. The low level way to do this, is to use pointers, initialize them to 0, change them when they should point to some initialized memory and change them back to 0 when the object they point to is deleted.
In C++, you can use Boost.Optional to spare you from messing around with pointers in this way.
you could during XML read, check the XML value and if it contains "!", assign a default value to whatever variable it is.
e.g. set ptr to nullptr, boolean to false and int to 0 or -1.
Use const default values whenever you can, that will make your code clearer and easier to maintain.
Related
My requirement is to parse on XML and populate an object. How do I automatically track if attribute xyz is present once the object is populated from the Xml. Please note that I will no longer have access to the parsed buffer after the object is populated. Hence I need some mechanism to know whether the attribute was present in XML and the same is populated in the object.
I have the below solution in my mind but not sure if anything more efficient possible. Also I am looking for a generic solution for this problem.
define a bit for each of the attribute in a class.
setter function should set that bit while parsing XML when attribute is present
getter function should check the bit before returning the attribute value by reference argument . It should return false when bit is not set. ( The getter function return type should be boolean and it accepts one argument which is of type attribute and populate it when present)
From your comment I gather that you can change the design, so this is what I would do:
Replace all optional members with the aptly-named std::optional or the boost equivalent if the former is not available.
using std::optional; // facilitates easy switching between std and boost if needed
class MyClass {
optional<int> some_value;
// Similarly for rest of attributes
void set_some_value(int value_to_store) { some_value = value_to_store; }
optional<int> get_some_value() { return some_value; }
}
To read from it do as follows
MyClass instance;
// ... parse XML and set attributes
auto some_value = instance.get_some_value;
if (some_value) {
do_something_with_int(*some_value);
}
Some notes on optional:
Default-constructed optionals are empty. This means that every attribute you don't explicitly set is empty by default.
Dereferencing an empty optional is undefined behavior. There are safer ways to access it. In this example it is safe because we manually checked for it since I assume you'd like to branch on the existence of your attribute anyway.
The managed object is guaranteed to be inside the allocated optional object. This means no dynamic allocation which is great for speed. If you have any huge objects, however, this can cause stack overflow issues. It's not likely, though, as most real world scenarios of large objects are using a string or some STL container/wrapper that holds its data on the heap anyway.
I couldn't find a mention of the space cost in the standard. I believe it is typically implemented with a single bool inside every optional object. sizeof(bool) is often sizeof(int). This makes it more space consuming than necessary, but it's as fast as possible. This is generally a good trade-off, but if you encounter memory usage problems and you have a lot of objects holding optionals you might need to find a more space-optimal solution. If you can use sentinel values to signal non-existence, look up implementations of compact optional objects.
SpiDeviceDriver::SPI_Error SpiDeviceDriver::SPI_ReadBytes(
quint32 size_,
QVector<quint8>& rxData_
)
{
//Get data and fill QVector<quint8> with data
}
I'm trying to call a class function (from another class) and pass in a QVector, then fill it with data.
I prefer to just pass in the QVector alone (without the quint32 size parameter) and then figure out the size from that and fill it with data according to its size. However, if the passed in QVector is size 0, I'd either have to assume it is meant to be size 1, creating a new spot for the data, or throw/handle the error at run-time, which i'd rather not do. Compile time error checking would be much better. Is there a better way to do this?
I guess you could pass in a quint32 size_ parameter, then forget what the size of the QVector is and force the resizing to be that size. This seems awkward as well
Note: I've been instructed by my boss to make every function return an enum error code, so just using a size_ and creating a vector, then returning that data is not an option.
So you want to read from a data source into the given vector. Apparently the application knows at run time how many bytes are expected, hence the idea of a size "in" parameter. But that is redundant: QVector (cf. http://doc.qt.io/qt-5/qvector.html#QVector-2) has a constructor which takes a size argument and a size() member function. Therefore, the expected number of bytes can be communicated by passing a vector of the proper size.
If that is deemed not explicit and obvious enough nothing except a certain redundancy speaks against a size parameter though. It would also bundle vector initialization code in the function.
Which leads to another alternative: To create and return a vector from the function (as value). Whether that is too costly depends on QVector's ability to be "moved" (doesn't look like it) or the compiler's return value optimization capabilities.
Error handling is another issue. The caller could check for short reads by inspecting the vector's size upon return. Shorter than required sizes indicate an error. If different reasons for error must be communicated there is a choice between exceptions or, indeed, error return values. The latter would imply to "return" the vector through some indirecting parameter.
Update regarding the special case of a request to read 0 bytes: This could also be handled as a legit (possibly diagnostic) request, as is done by the read() of the C standard library, cf. http://linux.die.net/man/2/read. If the line is ok, the return enum is "success" and the function does nothing and returns an empty vector. If an error condition is detected (no idea whether that's actually possible), the appropriate error is returned. Treating 0 byte read requests as NOPs fits nicely with many algorithms, the same way empty strings or vectors do.
That coding standard to return an error code with every function/method really, really sucks for C++. If you can find a way to persuade otherwise diplomatically, I would suggest trying.
You can use thread-local storage to set and retrieve global errors efficiently on a per-thread basis that you can poll any time. You also have exception-handling in C++ and can translate exceptions into error codes at appropriate API/transaction boundaries. It would also still be better to accept a contextual parameter by reference with every function where you can set the error code through it than be forced into returning error codes for everything.
That said, I've been there and done that with shoddy legacy-style coding standards.
So if you have no other option, I would suggest no to your idea of making the function work on a pre-sized version of rxData_ only.
If you are favoring that kind of output parameter type of design, strive to make it output-only when you can. It'll give your design a greater consistency. Don't get fancy with it. Pretend it is the return value. If you pretend that, rxData_ doesn't provide the function with any input information and you'd need size_ anyway.
Don't double up its responsibility as both input and output when you're using the reference like it's an emulated return value even though it's a parameter. That tends to lead to a confusing design and it'll make it difficult to make up your mind about it, so I'd suggest keeping both parameters and resizing the vector accordingly inside the function to match.
If it's an empty vector or one with a different size than intended, you would have had to resize it anyway outside, so you're not saving cycles. If it was the same size, then calling resize with the same size would generally be trivial as it would just skip the process.
Tcl: Interpreter creates copy of traced object whet it goes changed in this question I asked why does interpreter creates a copy of object in the trace? I understand that using handles is the right way here but it requires huge work, therefore I need workaround solution.
I need the code in the trace behave exactly the same as if it was written after set command. I need to change the object in the trace and I want the interpreter not to make a copy of object. It would be great if somehow disable the copying functionality in the trace function.
I have looked here http://www.astro.princeton.edu/~rhl/Tcl-Tk_docs/tcl/TraceVar.3.html but didn't find it.
DON'T DO THIS!
Changing the Tcl_Obj itself when there are multiple references held open to it (i.e., when Tcl_IsShared reports that the value is shared) can cause all sorts of semantic problems (many functions — e.g., Tcl_SetIntObj — specifically check and will abort the process if you try) so you need to be exceptionally careful. You're moving outside Tcl's semantics; there are dragons here!
To directly modify a Tcl_Obj, look at the bytes field of the structure (the length field is supposed to be kept as the strlen of bytes). That's writable; just change it, bearing in mind that it is always encoded as pseudo-UTF-8 (which is very straight forward for ASCII characters other than \u0000). If you want to change what is allocated, that field must be allocated with Tcl_Alloc. If bytes is NULL, there is no string representation; look to the internal representation for meaning.
The internal representation of a Tcl_Obj is determined by the internalRep union and the typePtr field. Understanding the meaning of the internalRep depends on understanding what typePtr points to; usually, if you didn't implement it, you shouldn't poke around at all. We do change what internal representations are present in patch releases sometimes. If you defined the typePtr to point to a structure you own, you'll know how to understand the internal representation. When the typePtr field is NULL, there is no internal representation.
Sometimes you may encounter a Tcl_Obj with neither internal nor string representation. DO NOT CHANGE THIS if you find one. It is reserved for the (very highly-shared) empty value.
While is technically possible to alter a shared object by poking around inside, the rest of Tcl assumes that you're not going to do this so it's pretty random what might break. You might even get away with it! But be aware that we won't formally support you; you're on your own.
We have a Java messaging API which we are translating to C++. The messages typically have simple data types, like string, int, double, etc. When a message is constructed, we initialize all the member variables to a default value which the API recognizes as a "null" value (i.e. never set to any value), e.g. Integer.MAX_VALUE for int types. Any fields which are considered null are not serialized and sent.
In Java, strings automatically initialize to null so it's easy to differentiate between a string field which is null versus a string which is empty string (which is a legal value to send in the message).
I'm not sure of the best way to handle this in C++, since the strings automatically initialize to an empty string, and empty string is a legal value to send over the API. We could default strings to some control character (which would not be a legal value in our API), but I'm wondering if there is a more conventional or better way to do this.
We're all new here to C++, so we may have overlooked some obvious approach.
The recommended way is to make is that the object doesn't exist until it has a valid value. If a message wit a null string isn't valid, why allow it?
You can't avoid it in Java, because a string can always be null.
But C++ gives you the tool to create a class which is guaranteed to always hold a string.
And it sounds like that's what you want.
For what you're asking for, the best approach is really to build into the class the invariant that objects of this class always have a string set. Instead of setting all the objects to some default value in the constructor, define the constructor to take the actual parameters and set the members to valid values.
However, if you want to specify an "optional" value, there are a couple of broad approaches:
either use a pointer (preferably a smart pointer). A pointer to a string can be null, or it can point to a valid string (which, again, may or may not be empty)
alternatively, use something like boost::optional from the Boost libraries. This is a clever little utility template which lets you define, well, optional values (the object may contain a string, or it may be null)
or you could simply add a bool flag (something like has_string, which, when not set, indicates that no string has been set, and the string value should be disregarded).
Personally, I'd prefer the last two approaches, but all three are fairly commonly used, and will work just fine. But the best approach is the one in which you design the class so that the compiler can guarantee that it'll always be valid. If you don't want messages with a null string, let the compiler ensure that messages will never have a null string.
To replicate Java "things can have values, or lack values", probably the most general way is to store boost::optional<T>, or in the next version of the standard, std::optional<T>.
You do have to throw in some * and -> if you want to read their values, and be careful about optional<bool> because its default conversion to bool is "am I initialized or not?", not the bool that is stored. But operator= does pretty much what you want it to when writing to it, it is just reading from it that can do unexpected things in a bool context.
To tell if an optional<T> is initialized, just evaluate it in a bool context like you might a pointer. To extract its value after you have confirmed it is initialized, use the unary * operator.
boost is a relatively high quality library with a high rate of code migrating from it to the C++ standard in 5 to 10 years. It does contain some scary parts (like phoenix!), and in general you should make sure that whatever component you are using isn't already in the C++ standard library (having migrated there). boost::optional in particular is part of their header-only libraries, which are easier to use (as you don't have to build boost to use them).
Many Win32 API functions have parameters specified to be "out". For example, GetIconInfo() description says about the second parameter that The function fills in the structure's members.
This implies that the function doesn't ever read the original values stored in the "out" parameter - only changes them - and therefore the caller is free to skip initialization.
Yet in one project I see the following:
ICONINFO ii;
::SecureZeroMemory(&ii, sizeof(ICONINFO));
if (::GetIconInfo(hIcon, &ii))
{
//do stuff, then
//release bitmaps
if(ii.hbmMask)
::DeleteObject(ii.hbmMask);
if(ii.hbmColor)
::DeleteObject(ii.hbmColor);
}
Is there any sense in that SecureZeroMemory() call? What could happen without it?
Well, in general I think initialisation is not needed, but good practice if you don't know exactly what the called function does with the values in the output variable.
In this specific case, the ICONINFO structure has two HBITMAP members which are essentially pointers to bitmaps. In the general case I'd say that if you are passing pointers to a function then you have to be certain that:
You pass in pointers that point to nothing and the
function you call creates the thing
pointed to for you and makes sure
your pointer points to it. (and probably leaves you to manage the newly allocated stuff) or
You pass in a pointer that points to
something (i.e. you allocated something for it) and the
function uses what you allocated.
The GetIconInfo() function fits the first case. So for clarity and perhaps even security it looks like a good idea to me to ensure the HBITMAP members of the ICONINFO structure are actually zero, rather than a random value that can lead to all kinds of nastiness further down the road.
So my verdict in this case would also be: not necessary but good practice.
Nothing. I mean if one is pretty sure that whatever is written there before call is discarded then there is no reason for doing that. But we don't know how internally the API will
function unless we developed the API, then it would be a good idea to initialize it.
This implies that the function doesn't ever read the original values stored in the "out"
parameter - only changes them - and therefore the caller is free to skip initialization.
Perhaps it isn't about the function reading the fields. Maybe its for detecting fields unfilled by the function? I don't know if this is necessary in this case, just pointing out that it might not be about reading.