5

I have this piece of code that compiles fine with clang (even with -Weverything), but for which gcc issues an error.

#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

class PhonebookWriter
{
public:

  PhonebookWriter(const string& fname):
    fname_(fname), names_(), numbers_() {}

  PhonebookWriter& operator()(const string& name,
                  const string& number)
  {
    names_.push_back(name);
    numbers_.push_back(number);
    return *this;
  }

  ~PhonebookWriter(void)
  {
    ofstream f(fname_.c_str());
    for(size_t i=0;i<names_.size();++i)
      f << names_[i] << " " << numbers_[i] << "\n";
    f.close();
  }

private:
  const string fname_;
  vector<string> names_;
  vector<string> numbers_;
};

namespace {
  void write_guests_data(const string& fname)
  {
    PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
  }
}

int main(void)
{
  write_guests_data("phone_book.txt");

  return 0;
}

and here's what I get when I try to compile the code:

$ g++ ./test.cpp
./test.cpp: In function ‘void {anonymous}::write_guests_data(const string&)’:
./test.cpp:39:27: error: declaration of ‘PhonebookWriter fname’ shadows a parameter
     PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
                           ^
./test.cpp:39:48: error: no matching function for call to ‘PhonebookWriter::PhonebookWriter(const char [11], const char [6])’
     PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
                                                ^
./test.cpp:39:48: note: candidates are:
./test.cpp:11:3: note: PhonebookWriter::PhonebookWriter(const string&)
   PhonebookWriter(const string& fname):
   ^
./test.cpp:11:3: note:   candidate expects 1 argument, 2 provided
./test.cpp:7:7: note: PhonebookWriter::PhonebookWriter(const PhonebookWriter&)
 class PhonebookWriter
       ^
./test.cpp:7:7: note:   candidate expects 1 argument, 2 provided
./test.cpp:39:49: error: expected ‘,’ or ‘;’ before ‘(’ token
     PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");
                                                 ^

My gcc version is 4.9.1, and my clang version is 3.5.0. I don't understand why there should even be a shadowing problem. Even if there were, it should have been picked up by clang.

5
  • Can you fix the shadowing problem so that both compilers are happy? Or are you saying you don't understand the error message at all? Commented Jan 31, 2015 at 18:19
  • 1
    This is interpreted as PhonebookWriter fname("Mr Foo Bar", "12345") it seems, i.e. as the declaration of a local instance. You might work around it using a temporary or a named factory function, or even just a pair of brackets around the PhonebookWriter(fname). Commented Jan 31, 2015 at 18:25
  • Yes, I can fix the shadowing problem in this specific example. However, I don't understand why there should be a problem in the first place, and also why different compilers respond differently to that code. Commented Jan 31, 2015 at 18:26
  • I was trying to avoid a temporary variable in the first place. Adding the extra brackets did the trick. Thanks. Commented Jan 31, 2015 at 18:29
  • 1
    Thread about the underlying issue: stackoverflow.com/questions/28283215/… Commented Feb 2, 2015 at 22:47

1 Answer 1

7

Change:

PhonebookWriter(fname)("Mr Foo Bar","12345")("Mrs Bar Foo","54321");

to:

(PhonebookWriter(fname))("Mr Foo Bar","12345")("Mrs Bar Foo","54321");

EXPLANATION

For some reason gcc removes the braces around fname, which turns the line into:

PhonebookWriter fname ("Mr Foo Bar","12345")("Mrs Bar Foo","54321");

And now the errors make sense.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.