rulururu

post Avoid making useless new object

June 4th, 2008

Filed under: .NET, C++ — Kai @ 3:16 pm

You often see statements like the one here when programmers want to check if a string has value or not.

if(strName!="")
{ ... }

For C++ programmers (who uses CString for example) this is correct and not really unusual - but please if you’re writing code in C# or another .NET language keep in mind that this causes the allocation of a new String object just for the reason to compare it with an empty string.

Correct implementations would be:

if(strName.Length <= 0)
{ ... }
 
if(strName.Length == 0)
{ ... }

You will not regognize this in a performance test or when using the application but it’s just good form to do it right - also because you know why you should do.

When working with CStrings it’s dispensable faster or slower to compare with an empty string or just to compare the length. If you have a look at the IsEmpty() member function of CString Class you’ll mention that I’m right:

bool IsEmpty() const throw()
{
     return( GetLength() == 0 );
}

post Correctly implement for() loop scooping

June 2nd, 2008

Filed under: C++, Visual Studio — Kai @ 2:13 pm

The following code snipped gives an error when compiling it with VC6, although it’s legal according to the C++ standart.

SomeFunction ()
{
    for (int i =0; i<5; i++)
    { ... }
    for (int i =0; i<10;i++)
    { ... }
}

Previously, the definition would be considered occurring outside of the braces, and would be in scope until the end of the outer enclosing braces (until the end of SomeFuncion() in the example above), so defining i in the second for loop gives a redefinition error.
Under the new rules, the variable definition is considered occurring inside the braces of the for() loop, and it goes out of scope at the end of the for loop, so both variable definitions given above would be needed.

It gives an error on the second for () complaining about i being redefined.

  • In VC7 (2002), the compiler was changed so that both conforming and
    non-conforming code was accepted, but neither interpretation was enforced -
    you could freely mix.
  • In VC 7.1 (2003), the /Zc:forScope option was introduced and was by-default
    turned off, preserving the VC7 (and earlier) behavior.
  • In VC8 (2005), the default was changed so that the option is on by default.
  • VC9 (2008) changes nothing with regard to for-loop variable scoping.

So, what do you do if you need the new scooping rules?

A tumb rule is that you can turn it off, and get the VC6 behavior, by adding /Zc:forScope- to
your compiler options in the project properties dialog.

The following macro has been suggested as a workaround:

#define for  if (0) {} else for

However, using a macro to change the semantics of a program is generally not a good idea, and should only be used in extreme cases, such as when trying to compile code developed under a compiler that implements the new rule. Applying the macro to code developed under the original rule can result in silent behavioral changes, as described above. A compiler that implements the new rule can warn about code whose interpretation differs under the old and new rules, so it’s best to wait for proper compiler support, if you can.

Another way you can go is to use the preprocessor macro MSC_VER and create conditional compilation blocks, or simply define the varibable outside of the first loop and set initialize it every time again.

Yet another workaround is to enclose each for() sentence in braces, like this:

{
    for ( int i = 0; i < 10; i++ )
    {
        //  ...
    }
}
{
    for ( int i = 0; i < 12; i++ )
    {
        //  ...
    }
}

This effectively creates yet another scope that hides the for-loop scooping bug. However, it adds unnecessary scopes and is easy to forget to close one of them or them alltogether.

ruldrurd
« Previous Page
Powered by WordPress, Content and Design by Kai Bellmann
Entries (RSS) and Comments (RSS)