Tag Archives: C++

Function Chaining in C++

Function chaining is a construct in  C++. It constructs a chain of function calls in one statement. Return value of the previous function call is used to call the next function and hence a chain of function calls is created. Following is an example of it:

obj.func1().func2().func3();

obj.fun1() is an expression which evaluates to the return-value of func1(). On this returned-value func2() is called which again evaluates to its return value. Similarly func3().

Function chaining is good as well as bad. It may make the code look compact and nice but excessive use may end up with readability and maintenance issues. The code may be difficult to debug also. One can’t see the intermediate return values of the function calls.

Apart for the readability and debugging issues, it can also result into a serious memory issue. Lately, I faced it while converting from a QString to a char* C string. Here is the code:

// function QString::toLocal8Bit() returns QByteArray
// QByteArray::data() returns pointer to internal data

QString str("manjeet");
const char *c_str = str.toLocal8Bit().data();
// c_str is now a dangling pointer referring to an invalid memory

In the above code c_str points to an invalid memory.

It happens because the function chaining involves unnamed temporary objects. These unnamed temporary objects are returned by the function calls. And these are again used to call the next function call. But in this case the last temporary object is not stored and is deleted after the statement is complete.

This code can be fixed by avoiding the function chaining and storing the intermediate object.

QString str("manjeet");
QByteArray ba = str.toLocal8Bit();
const char *c_str = ba.data();

Here the problem is fixed as the byte array is now being stored the ba variable.

[1] http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr382.htm

[2] http://stackoverflow.com/questions/154864/function-chaining-how-many-is-too-many

Use QRegExp Carefully

Lately, I found a silly mistake which I have repeated at a couple of places in my Qt code. I thought of noting it down.

Example Case

I have a QStringList (list) and I want to find the index of a string (str) in it.

// list     -  QStringList
// str      -  QString

int index = list.indexOf(QRegExp(str));
// this function accepts QRegExp only, though
// in the new releases of Qt an overload
// accepting QString is also available

Nothing wrong with this, it has been working great for me and I have used it at many places. But, this works as long as str doesn’t contain any RegExp special characters. If the str contains special characters, its meaning changes. For instance dealing with filePaths, filepaths may have special characters in it like the character +.

The meaning of QRegExp(str) changes if str has the character +:

  • str
    /home/dahiya/test+examples/newFile
  • QRegExp(str)
    /home/dahiya/testexamples/newFile
    /home/dahiya/testtexamples/newFile
    /home/dahiya/testttexamples/newFile
    /home/dahiya/testtttexamples/newFile
    /home/dahiya/testttttexamples/newFile

It will never match the original string (str). The index returned will be not be the valid one.

Solution

Escape all the RegExp special characters. On escaping the special characters, they will be treated normal and the code will behave correctly. Qt provides a utility function also.

QString QRegExp::escape(const QString&)

This function returns the escaped string (str).

  • str
    /home/dahiya/test+examples/newFile
  • escape(str)
    /home/dahiya/test\\+examples/newFile

So one can write the correct code like:

int index = list.indexOf(QRegExp(QRegExp::escape(str)));

Conclusion

In future, use QRegExp carefully if you just want to match a string.

QXmpp 0.3.0 Release

I’m glad to release the next version of QXmpp, version 0.3.0. It comes packed with a number new features, bug fixes and improvements.

Here is a list of new features in QXmpp 0.3.0, please look at the changelog for exhaustive list:

  • XEP-0153: vCard-Based Avatars
  • XEP-0202: Entity Time
  • Managers for all the XEPs
  • More examples:
    example_9_vCard: vCard handling
    GuiClient: Graphical chat client, test bench for QXmpp functionalities
    example_8_server: Server capability
  • Server framework: Yes you can write a server now look at the example example_8_server
  • Add support for DNS SRV lookups, meaning you can connect to nearly all servers using only a JID and a password. No need to explicitly specify the server information.
  • Add QXMPP_VERSION and QXmppVersion() for compile and run time version checks.
  • Improve code documentation coverage and quality.
  • Completely remove dependency on QtGui, making it easier to write console applications.

QXmpp 0.3.0 Release Details:

Project Page | Changelog | Readme | API Documentation | Download

As usual, thanks to the authors, community and the users who have been driving the project.

About QXmpp:

QXmpp is a cross-platform C++ XMPP client (and server!) library based on Qt and C++. It is an open source project licensed under a permissive license LGPL. As of today, the project is around two years old.

Implementing XOR Encryption

At times, you need a simple encryption and decryption functionality to secure sensitive information. In my case, I needed to store passwords on disk to implement the “Remember Password” functionality of the GuiClient example of QXmpp.

Instead of going for a 3rd party library where you just need a very basic crypto functionality I will suggest using XOR encryption. XOR encryption is pretty easy to implement. I will also present my implementation of this algorithm using Qt C++.

XOR (Exclusive OR) Encryption or XOR Cipher is a simple symmetric encryption algorithm. It operates according the principle that XORing a data twice with the same key results in the same data.

The first XOR of the data and key gives the encrypted data. Then the decryption involves XORing the encrypted data with the same key.

EncryptedData  = Data ^ Key
Data =  EncryptedData ^ Key

Data: data to be encrypted
Key: secret key or password
EncryptedData: data after encryption
^ represents Exclusive-OR (XOR) operation

Example:

Let us use two binary numbers for Data and Key. The 

Data  = 01101
Key   = 10101

Encrypt:

EncryptedData = Data ^ Key
EncryptedData = 01101 ^ 10101
EncryptedData = 11000

Decrypt:

Data = EncryptedData ^ Key
Data = 11000 ^ 10101
Data = 01101

Implementation of XOR Encryption in Qt C++:

QByteArray calculateXor(const QByteArray& data, const QByteArray& key)
{
 if(key.isEmpty())
   return data;

 QByteArray result;
 for(int i = 0 , j = 0; i < data.length(); ++i , ++j)
 {
   if(j == key.length())
     j = 0;// repeat the key if key.length() < data.length()
   result.append(data.at(i) ^ key.at(j));
 }
 return result;
}

C++ Surprise: switch-case declaration-without-initialization

I have been programming in C++ for a long time and it keeps surprising me. C++ Programming Language is full of surprises. Lately, I found an interesting one.

The Surprise!

I never declare new variables/objects in the case statements. To me, it is not allowed. If I ever need new variables/objects in a case statement, I use braces. Braces define a valid scope for the new variables, the new variables are not valid outside the braces. Without using the braces, variables declared in a case statement are visible in the succeeding cases as well. And these declarations can be skipped if the switch jumps to those cases.

The surprise is that declaration is possible! But only for a very specific case, the declaration without initialization. int var; is such example.

The declaration without initialization is possible only for POD types (plain old data, collection of basic types, C structs based on basic types, pointers, enums etc.). Therefore, to be precise, the declaration in a case statement is possible only for POD types and without initialization.

Declaration without initialization [Allowed, Surprise!]

  • int count;
  • float length;
  • int* ptr;

Declaration with initialization [Not allowed as expected]

  • int count = 20;
  • float length = 6.7;
  • int* ptr = 0;
  • std::string str;       // involves call to default constructor (initialization)
  • std::string str2(“manjeet”);

Example

In the following code. I have marked the statements Valid/Invalid as per g++ and MSVC. Let us look at the unexpected and expected statements.

std:string str1("test");

switch(i)
{
case 0:
 int var1;                  // VALID

 int var2 = 22;             // INVALID

 int var2;                  // VALID
 var2 = 22;                 // VALID

 str1 = "test";             // VALID, defined before switch statement
 std::string str2("test");  // INVALID
 break;
case 1:
 break;
case 2:
 break;
default:
 break;
}

Surprise:

  • Line#6: Valid, int var1;
  • Line#8: Invalid, int var2 = 22; if Line#6 is valid then this should also be valid.

Expected:

  • Line#11 & 13: Valid, usual assignments.
  • Line#14: Invalid, declaration of an object. It is not allowed, very much expected.

Explanation

As per the C++ Standard ISO/IEC-14882-2003 section 6.7.3

It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).

Therefore according to the above rule, jumping past a declaration with initialization is not allowed. And the only exception to this rule could be a declaration of a POD types. Because POD types can be declared without initialization.

int a;  // declaration without initialization

And for non-POD types declaration-without-initialition is never possible. The object can’t be declared without initializing because the constructor will always be called.

std::string str;    // declaration that includes initialization, constructor is called

Rationale Behind the Rule

The question pops up to the mind.

Why is jumping past a declaration-without-initialization allowed?

I don’t have the answer. But it might have something to do with followings:

  • All the initializations of the variables and objects are done at the compile time. Whereas assignments during the runtime of the program.
  • If initialization doesn’t takes place the destructor should not be called. But the destruction always takes place when the object goes out of scope. Destruction without construction doesn’t sound good. Therefore the execution should not jump an initialization.

Conclusion

  • Declaration of POD types without initialization is allowed in a case statement.
  • Declaration of non-Pod types can only be done in the braces only.
  • In a switch-case, all the case statements are in the same scope.
  • The switch-case is nothing but a collection of goto and labels.
  • goto-label jump is not allowed if jump skips declaration with initialization.
  • Good practice would be to always use braces after case statements if declarations are involved.

References

  • C++ Standard ISO/IEC-14882-2003
  • http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=171
  • http://www.fnal.gov/docs/working-groups/fpcltf/Pkg/ISOcxx/doc/POD.html
  • http://www.parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.7

QXmpp 0.2.0 Release

Last year, I founded an open source project QXmpp. It is an XMPP client library based on Qt. It is licensed under a permissive license LGPL. The project is now more than a year old. The very first public release QXmpp 0.1.0 was made on June 14, 2009. And last Sunday, we released QXmpp 0.2.0.

QXmpp 0.2.0 comes with numerous features (many XEPs and new authentication schemes), many bug fixes, architectural improvements and Doxygen documentation. Have a look at the Changelog for a complete list of new features and changes in this release.

Thanks to the authors, group and our users who have contributed in the form of patches, bug reports and suggestions.

QXmpp 0.2.0 Release:

Project Page | Changelog | Readme | API Documentation | Download