3

I'm trying to take a Qt C++ project originally written for Windows and cross compile it for embedded Linux. Now this program compiles find and works on Windows, so this problem must be something OS specific (which I didn't think happend with Qt code) or configuration related, but I'm having a hard time tracking it down because I don't fully understand C++ syntax.

my make command:

arm-linux-gnueabihf-g++ -c -march=armv7-a -marm -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a8 -O2 -O3 -Wall -W -D_REENTRANT -DCHL80Net -DPHASE_TO_NEUTRAL -DCHL80NET -DCANLCD_BUILD -DQT_NO_DEBUG -DQT_XML_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I../mkspecs/qws/linux-am335x-g++ -I. -I../include/QtCore -I../include/QtGui -I../include/QtXml -I../include -I. -IApp -IApp/Model/ModelSim -IApp/Model -I. -IPages -IApp/GUI/Widgets -IApp/GUI/Pages -IApp/GUI -IApp/GUI/Widgets -IApp/GUI/Pages/Util -IApp/GUI/Pages -IApp/Log4Qt -I.obj -o .obj/CanInterface.o App/Can/CanInterface.cpp

The error:

App/Can/CanInterface.cpp: In member function ‘void CanInterface::closeConnection()’: App/Can/CanInterface.cpp:68:5: error: ‘::close’ has not been declared make: * [.obj/CanInterface.o]
Error 1

Here's the line of code in question:

void CanInterface::closeConnection()
{
    ::close(m_socket);
    m_socket = -1;

I thought this didn't look like valid code at all at first, but I don't really know C++ so I had to do a little research, it seems like this ::function() syntax is to ensure resolution occurs from the global namespace instead of the local one.

So what I'm trying to find out is what namespace should have declaired this close() function. If my understanding of this code is correct I don't need to look in the CanInterface class for the undeclaired function, but it's parent class?

In the header file for the CanInterface class I found this:

class CanInterface : public QObject 
{
        Q_OBJECT

which I think means that it inharents from a QObject class. So:

  1. Am I on the right track?
  2. How do I know if I need to look at the QObject class for the missing close() function or if I need to keep going up? Does ::close somehow tell me how many levels of nested classes I need to search through?
  3. Any other ideas or tips for further investigating this?
Mike
  • 47,263
  • 29
  • 113
  • 177
  • 1
    In answer to #3: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – John Dibling Feb 05 '14 at 15:42
  • @John maybe some day I'll have time to read more, but for now I just have to get the job done. I'm a C programmer, this is outside my element and I *shouldn't* have to touch C++ again... i hope... – Mike Feb 05 '14 at 15:44
  • Can you find out in a windows IDE what `close` is supposed to be? – juanchopanza Feb 05 '14 at 15:46
  • [`::close` should be declared in ``](http://linux.die.net/man/3/close). – Casey Feb 05 '14 at 15:47
  • 1
    @OlafDietsche He knows what `close()` does in a C program, but not that `::close()` in a C++ program is intended to invoke the same function. – Casey Feb 05 '14 at 15:50
  • @Casey, Mike Ok, sorry for the noise. – Olaf Dietsche Feb 05 '14 at 15:52
  • @Casey - OK, that's exactly the answer I needed. `::close()` is `close()` got it. And I see `unistd.h` was not included in the `extern "C"` list, that is the problem. Thanks very much. – Mike Feb 05 '14 at 15:56

2 Answers2

4

You are correct, in that ::some_function() calls a function from the global scope.

This includes all C library or system functions. You can lookup global functions on a *nix system with man, e.g.

man close

which gives on my Ubuntu

NAME
       close - close a file descriptor

SYNOPSIS
       #include <unistd.h>

       int close(int fd);

So, to fix your compile error, you must include unistd.h somewhere in your C++ source or in a surrounding header file.

You can get the same information, when you google for man close, e.g. http://linux.die.net/man/2/close

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
3

C++ encapsulates names in namespaces to avoid naming collisions. It's somewhat analagous to the C practice of prepending a prefix specific to a library to the names of functions in that library, e.g., my_library_foo() in C might be called my_library::foo() in C++. When :: appears at the beginning of a name, it means that name is fully qualified: it is looked up beginning from the global namespace instead of the current/enclosing namespace, much like with absolute (/etc/passwd/) vs. relative (foo/bar) file names.

So the name ::close is intended to resolve to the close function declared in the global namespace, the one which would be put there by including <unistd.h> on a POSIX system.

Casey
  • 41,449
  • 7
  • 95
  • 125
  • Thanks for the input. I guess I was equating `::` to `..` in my head and thinking it would be "up one level" instead of literally a "top most" function call. That was a very helpful explanation. – Mike Feb 05 '14 at 16:01