Koenig look-up and namespaces

I was running through some of the posts on codeguru and then suddenly saw this name referenced in Andreas Masur's post - "Koenig Lookup". I had heard it for the first time since I started with C++ and to be specific namespaces. So, I though of starting a look-up for myself and find what it really was! This post would be an introduction to the concept which we frequently use knowingly and most of the times unknowingly. Here it goes:

Keonig look-up is an algorithm devised by Andrew Koenig. This algorithm is also sometimes known as Argument-dependent Lookup. These days, it is used in all the standard conforming compilers in C++ which handle cases as shown in the example code below:

[CODE]
namespace MyNamespace{
class A {};
void func(A);
}

MyNamespace::A a; // global object of MyNamespace::A class.

//main method.
int main(){
func(a); // OK - MyNamespace::func is called.
}

Neither a using-declaration nor a using-directive appears in code above. And yet, the compiler will do the needful and that is correctly identifying the unqualified name "func" as the function declared in namespace MyNamespace by applying the algorithm we are talking about. How does it work? The algorithm tells the compiler to look at not just the usual places such as local scope, but also the namespaces that contain the argument's type. Thus, in the following line of code, the compiler finds that the object a, which is the argument of the function func, belongs to the namespace MyNamespace. So, it looks at that namespace to locate the declaration of "func", "guessing" what we wish to do.

Without this, namespaces would be imposing an unacceptable burden on the programmer, who would have to repeatedly specify the fully qualified names, or instead, use numerous using-declarations. There is abundant debate on the topic of advantages and disadvantages of this algorithm but lets see this example to support this feature.

[CODE]
#include
using std::cout; //using declaration
int main(){
cout<<"hello world!"; //OK, operator <<>
}

The using declaration puts std::cout into the scope of main(), thereby enabling us to use the non-qualified name "cout". However, the overloaded <<>

[CODE]
std::operator<<(cout, "hello world!");

Isn't it a pain-saving appreciable feature. It's interesting to find out about things that we usually do unknowingly. It add value to our knowledge. Cheers.

Casting cv-qualifier and function pointers to void*

Okay..so this is my first post to this blog of mine. This post is a result of a very fine discussion that I had with some of the Gurus at http://www.codeguru.com. I thought I would compile the stuff from that and present it here.

Before I proceed any further I would like to thank the members of Codeguru who participated with keen interest and helped me get the concept right. Thanks to - Graham, SuperKoko, Smasher/Devourer, Wildfrog, NoHero and Improving.

The question was - Can void pointers point to const, volatile and function pointers? Explain.

The answer is - Quotes from MSDN:
"If a pointer's type is void *, the pointer can point to any variable that is not declared with the const or volatile keyword."
AND
"A void pointer can point to a function, but not to a class member in C++."

Thats pretty much it but lets go through the explanation to get to the basic reasons why MSDN negates the possibilities.

const and volatile are collective named as cv-qualifiers by the standard and a basic principle is that we are not allowed to lessen the amount of cv-qualification of an object. If we were to assign a cv-qualified object to a void pointer, then we could cast them back to a non-cv-qualified pointer to the original object. This steals away the whole essence of the cv-qualification of the objects while the intention of the standard is that only const_cast can remove cv-qualification from an object.

The standard treats const and volatile identically as far as their syntax and restrictions are concerned. The standard intentionally makes it hard for us to lose the cv-qualification of an object, since this is almost always an error in coding, not that its impossible.

You could use this as an example:
[CODE]
volatile int arg = 0;
void * ptr1 = &arg; // Valid but it won't be volatile anymore

A better way to do this could be:
[CODE]
volatile int arg = 0;
volatile void * ptr1 = &arg;

Okay, so that's for the CV-qualifiers. Now lets get back on track with the case of function (class-member functions as well as non-member functions) pointers.

Let's take an example:
[Code]
#include<iostream>
using namespace std;

//This creates a typedef called IntFuncPtr which is a pointer to a function
// that takes no arguments and returns an int.
typedef int (*IntFuncPtr)();

// An example class with a single member function.
class A {
public: int f() { return 1; }
};

//Note this function has the proper signature to be addressed by an IntFuncPtr.
int g() { return 2; }

int main() {
void *pVoid;

pVoid = g; //OK: cast from int (*)() to void*
cout << ((IntFuncPtr) pVoid) () << endl;
pVoid = A::f; //ERROR: can't cast from int (A::*)() to void*
return 0;
}

In this program, Visual C++ 6.0 will allow to make an implicit conversion from a (non-class member) function pointer to a void pointer, in the line pVoid = g. In the following line, we cast that pointer back to its appropriate type and use it to call the function it points to, to demonstrate that it holds the correct value. The line after that, attempting to assign a class member function pointer to a void pointer, does not work.

So, we see that we can use void* to point to non-member functions but not member functions. Is this really true?? Even if we are able to get the non-member functions part going, is it portable??? Comeau compiler is considered to follow the C++ standards to the closest and running this code there did not allow what VC++ allowed easily. It gave the following error message - "A value of type int (*)() cannot be assigned to an entity of type void*."

The reason for this is well explained by Herb Sutter in his More Exceptional C++. He says : "Although a void* is guaranteed to be big enough to hold the value of any object pointer, it is not guaranteed to be suitable to hold a function pointer; for example, on some platforms a function pointer is larger than an object pointer." That is, in general, for a member function pointer or a non-member function pointer.

Here's an example that illustrates this for the case of member function pointers:

[CODE]
#include<iostream>
using namespace std;

class A
{
public:virtual void f();
};

class B
{
public:int x;
};

class C : public B, public A
{
};

int f()
{
return 0;
}

int main()
{
void *p=reinterpret_cast<void *>(f);
cout << sizeof(&A::f) << " "<< sizeof(static_cast<void (C::*)()>(&A::f)) << endl;
return 0;
}

Outputs:
8 8 (With GCC)
12 12 (With BC++)
4 8 (With VC++)

While sizeof(void*) will gives you 4, with above.

You might get better affirmative results for classes with simple inheritance but with multiple inheritance (the case in the program), virtual inheritance, virtual functions and in some more complex scenarios, you could get the size of the function pointers greater than sizeof(void*), may be 4, 8 and sometimes 12 or even greater. They are very compiler dependent and class dependent.

You can't even assign a pointer to non-member functions to a void* for the same reasons (even if some compiler would allow you doing so), they are not guarenteed to be of the same size. These are however relatively portable than the case of member-function pointers and that is why MSDN says you can (for non-member functions) atleast on MS platform. But, you know that's not portable. A work-around could be using reinterpret_cast to cast a function pointer to another function pointer type (say, any one that you can use throughout your code base for consistency) and then cast it back to it's original type. The standard guarantees that to work. But the drawback is that you lose type-safety, which itself is not a very good thing to do in ideal scenarios.

Further reading and references: online Comeau compiler at Comeau online , Recursive Declaration.

Cheers!!!

TechNewsWorld


Today I found a good web site which consists of news on new Techs. That is www.technewsworld.com. Seems it provides news in all most all the techincal fields. I was mainly focused on the Open Source portion.

Some of the interesting news I found today are;

  • Firefox Patch
    Patch releasing has two practices. One is to release patches at the end of each month and the other is to realese as soon as it is ready.
    I feel that patch releasing as soons as possible is the best way since recovery of an attack will be much harder than applying a patch even in a large scale organization.

  • One-in-Ten-Web-Users-Have-a-Taste-for-Spam
    As the news explains 39 percent of the people still reading the messages and clicking on links embedded in the emails. As they says, this is a known method for spammers to detect if an email address is being used, and as a result 57 of the latter group reported that they started receiving more spam.

  • Sun-Open-Sources-Its-Authentication-Technology
    Sun Microsystems moves towards Open source. But I wish the complete java platform not to become Open-Source.
  • Google News

    "Google News" provides a well organized and a customizable view for NEWS.

    You can customize the viewed news by providing key words. And also the news can be prioritize according to your requirements. So news searching and organizing is done by Google, we just have to watch it.



    http://news.google.com/


    I have created a customized News View for me. You can check my configurations and even you can use that as your customized view.

    My Customized News View

    Learning C++

    This blog would be a collection of some quality issues related to the C++ Programming Language. A compilation of my activities on Codeguru. Hope this comes out to be of help to you people and of course me.

    Cheers to my 2nd blog.
    [ http://abnegator.blogspot.com ]

    JASIC?

    Someone recently mentioned a new up and coming BASIC language product called KBASIC and asked me what I thought. I went to Google and found the site. What I discovered there was so complicated that it reminded me of programming in Java using the Eclipse IDE. Eclipse is an excellent IDE, at least in the sense that it makes programming in Java practical (possible?). You need all the power of Eclipse because Java is a big, heavy and complicated way to write software.

    KBASIC seems to emulate Java. Even the style of object orientation presented is very Java-like or C#-like and some syntax is borrowed directly from Java. Why do this? BASIC shouldn't need an industrial strength IDE that is as complicated as the cockpit of an F-15.

    This is the sort of thing I am trying to avoid with the new BASIC programming language I'm working on. Java is a mountain of rules and exceptions that the programmer must navigate, never forgetting to dot i's and cross t's. Why make a BASIC that emulates Java? This is the sort of thing that caused outcry when Microsoft did away with Visual Basic and replaced it with VB.Net.

    I know that some people enjoy mastering complexity, perhaps as a way to find satisfaction in their work. This is incompatible with the way BASIC programming should be. BASIC should be small, simple and fun.

    On Modernizing BASIC

    dave b. responded to my previous post with this (amongst other things):
    I hope this nostalgia over the old BASIC command set and the "small is beautiful” fallacy won't hold LB back from evolving into something really useful (which is what programming languages should be).


    Really useful for what, Dave? Go and ask the Liberty BASIC community if Liberty BASIC is useful and they will answer with a resounding yes. It is useful for getting a quick program together, useful for learning to program, useful for having fun with a computer, and more too. To make a comparison, Java is also a useful programming language, but it isn't necessarily useful for the same things. There is no universally useful programming language.

    I agree with a lot of your ideas, and if you read all of my posts, I think you'll agree that I don't have the simplistic mindset that you seem to imply that I have. I understand abstraction in software better than you apparently think I do.

    Nostalgia has nothing to do with Liberty BASIC's faithfulness to classic BASIC syntax, at least not on my part. This is a matter of marketing. You welcome the C-style of doing things with functions. A lot of other people do not. They want an old-style BASIC. I am marketing to these other people. Your advocacy of mutating BASIC syntax into something that is more "modern" does create a new language that is not BASIC, IMHO. Eliminating old BASIC commands and replacing them with functions turns a lot of people off.

    I am working on a new BASIC in part to break the backwards compatibility chain with Liberty BASIC. That doesn't mean of course that my new language will necessarily take the direction that you advocate. OPEN "filename.ext" for INPUT as #1 will still be there. I agree with your point that the syntax for controlling widgets in Liberty BASIC is bad, and it will be replaced in the new BASIC. I will do things differently and in an unexpected way, and not to be deliberately contrary but for a reason. I intend to lead with this new language, not follow.

    BTW, a lot of people like Liberty BASIC the way it is and don't seem to need anything else. You have decided to move on to another tool that meets your needs better and that's great.

    Don't expect Liberty BASIC to become anything but what it is. This is beginning to feel like you're beating a dead horse. :-/

    Check out this stream