0

I want to know how preprocessor directives are evaluated, when they are placed in a loop in C/C++? Following is the code, which uses directive in a for loop, but it doesn't work. Why is it so?

main.cpp

#include <stdio.h>
class Student
{
public:
    int roll;
    int marks;

    Student()
    {
        roll = 10;
        marks = 0;
    }
};    

int main()
{
    printf("Hello, World!\n");
    int iCounter;

    char attr[][6] = {"roll", "marks"};

    Student std;

#define PRINT1(std, X) printf("%d", std.##X);
    for (iCounter = 0; iCounter < 2; iCounter++)
    {
        PRINT1(std, attr[iCounter])
    }

    return 0;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Mangu Singh Rajpurohit
  • 10,806
  • 4
  • 68
  • 97
  • Why should it? `attr` is no member of class `Student`. – cadaniluk Jul 17 '15 at 10:49
  • 2
    _[devil's advocate for Q&A quality purposes, because in reality I can guess what you mean here]_ How are we supposed to know your definition of "working" by only reading code that, by your own admission, _does not exhibit a valid implementation of that definition_? And why is this tagged C? – Lightness Races in Orbit Jul 17 '15 at 10:50
  • 1
    I think you need to [read a book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) and understand how C++ and the preprocessor work, because this is not at all valid code. – TartanLlama Jul 17 '15 at 10:51
  • 3
    "it doesn't work" is not a good description of a problem. Please tell us what behavior you experience (compile/runtime error?). Also: please do not use `std` as a variable name, because this is also a standard namespace. – KompjoeFriek Jul 17 '15 at 10:51

1 Answers1

1

The preprocessor is a pre-compilation phase. It is essentially a code generator and, as such, has no knowledge of or interaction with your for loops.

You simply cannot iterate over a class's members in this manner.

Here's what your preprocessed code looks like (I've omitted header expansions for obvious reasons):

class Student
{
public:
    int roll;
    int marks;

    Student()
    {
        roll = 10;
        marks = 0;
    }
};    

int main()
{
    printf("Hello, World!\n");
    int iCounter;

    char attr[][6] = {"roll", "marks"};

    Student std;

    for (iCounter = 0; iCounter < 2; iCounter++)
    {
        printf("%d", std.attr[iCounter]);
    }

    return 0;
}

As attr is not a member of std (terrible name for an object; please change it), hopefully you can now see how this is not going to "work" as you intend.

Furthermore, your macro is actually inherently broken and produces an error, because you are using ## where you shouldn't. Even if this code were what you wanted, the proper definition would be simply:

#define PRINT1(std, X) printf("%d", std.X);
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055