mardi 28 juin 2016

Why does a member function exist only once even defined in one multiple included .h file?

I am just wondering how the compiler can handle the situation where a member function is declared & defined only in a include file but this .h file is included multiple times in different source codes without complains of the linker regarding multiple definition of ....

foo_1.h:

class foo
{
public:
    auto in_include() -> void { printf( "in in_include()\n" ); }
    foo();
};

foo_1.cpp:

#include <stdio.h>
#include "foo_1.h"

foo::foo()
{
        printf( "in foo()\n" );
        in_include();
}

and finally foo_main.cpp:

#include <stdio.h>
#include "foo_1.h"

int main()
{
        foo fooObject;
}

These MCVE compiles and links fine and produces the expected output:

in foo()
in in_include()

BUT, when I add in foo_1.h this line int globar_var; then the linker complains [as I expect it]:

/tmp/ccfjJJAT.o:(.bss+0x0): multiple definition of `globar_var'
/tmp/cciob9sM.o:(.bss+0x0): first defined here

Initializing a 2D vector in member initializer lists of variable size?

I'm looking to initialize a 2D vector in the member initialization list of a constructor, but I want the size of it to be variable so I can pass that in as a parameter.

If I have the 2D vector member below:

std::vector<std::vector<int> > myVectorMember;

And this is my constructor:

MyClass::MyClass(int x, int y)
: myVectorMember(x, std::vector<int>(y, 0)
{}

Then I get the error:

error: array initializer must be an initializer list
: myVectorMember(x, std::vector<int>(y, 0)
  ^

What is the correct way to do this if any?

Using VLAs in a C++11 environment

I got C-Code that already exists and that makes use of C99-style VLAs. Like this one:

 int foo(int n, double l[n][n], double a[n][n]);

I'd like to include the headers in my C++11 project. As C++ doesn't allow these kind of constructs I'm using extern "C" to include these header files. However the compiler doesn't like this at all.

./header.h:23:42: error: use of parameter outside function body before ‘]’ token
 void foo(int n, double l[n][n], double x[n], double b[n]);
                           ^
./header.h:23:45: error: use of parameter outside function body before ‘]’ token
 void foo(int n, double l[n][n], double x[n], double b[n]);
                              ^
./header.h:23:46: error: expected ‘)’ before ‘,’ token
 void foo(int n, double l[n][n], double x[n], double b[n]);
                               ^
./header.h:23:48: error: expected unqualified-id before ‘double’
 void foo(int n, double l[n][n], double x[n], double b[n]);
                                 ^~~~~~

I think I read somewhere that VLAs became optional in C11. Does this mean that gcc got rid of it completely? If so what can I do other than extern "C"? Of course I can compile the source with an older C-standard. But I have to include the headers somehow. Any idea?

Rewriting the whole thing would only be a method of last resort.

Compile time replacement of string constants with integers

I have a list of pre-defined mappings of string constants to numbers outside of my code base. The integers map to data inside of the program but I want to use the far more readable string constants in my code. The resulting binary should only contain the numbers and not contain the string constants at all. Is it possible to replace the string constants with the mapped integer at compile time?

What I want to achieve is basically having this code:

getData("a string constant here");

and I want to transform it into this:

getData(277562452);

Is this possible via macros or constexpr?

Compute shader not writing to SSBO

I'm writing a simple test compute shader that writes a value of 5.0 to every element in a buffer. The buffer's values are initialized to -1, so that I know whether or not creating the buffer and reading the buffer are the problem.

class ComputeShaderWindow : public QOpenGLWindow {
  public:
    void initializeGL() {
        // Create the opengl functions object
        gl = context()->versionFunctions<QOpenGLFunctions_4_3_Core>();
        m_compute_program = new QOpenGLShaderProgram(this);
        auto compute_shader_s = fs::readFile(
                                    "test_assets/example_compute_shader.comp");
        // Adds the compute shader, then links and binds it
        m_compute_program->addShaderFromSourceCode(QOpenGLShader::Compute,
                compute_shader_s);
        m_compute_program->link();
        m_compute_program->bind();

        // Fills the buffer with -1, so we know whether the problem
        // is the compute shader not being invoked or not reading
        // the buffer correctly afterwards.
        GLfloat* default_values = new GLfloat[NUM_INVOCATIONS];
        std::fill(default_values, default_values + NUM_INVOCATIONS, -1.0);
        GLuint ssbo;
        gl->glGenBuffers(1, &ssbo);
        gl->glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
        gl->glBufferData(GL_SHADER_STORAGE_BUFFER,
                         NUM_INVOCATIONS,
                         default_values,
                         GL_DYNAMIC_DRAW);
        gl->glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
        gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
        gl->glDispatchCompute(NUM_INVOCATIONS / WORKGROUP_SIZE, 1, 1);
        gl->glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
        gl->glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
        gl->glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);

        // Now map the buffer so that we can check its values
        GLfloat* read_data = (GLfloat*) gl->glMapBuffer(GL_SHADER_STORAGE_BUFFER,
                            GL_READ_ONLY);
        std::vector<GLfloat> buffer_data(NUM_INVOCATIONS);

        for (int i = 0; i < NUM_INVOCATIONS; i++) {
            buffer_data[i] = read_data[i];
        }

        gl->glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);

        for (int i = 0; i < NUM_INVOCATIONS; i++) {
            DEBUG(buffer_data[i]);
        }
        assert(gl->glGetError() == GL_NO_ERROR);
    }

    void resizeGL(int width, int height) {

    }

    void paintGL() {

    }

    void teardownGL() {

    }

  private:
    QOpenGLFunctions_4_3_Core* gl;
    QOpenGLShaderProgram* m_compute_program;
    static constexpr int NUM_INVOCATIONS = 9000;
    static constexpr int WORKGROUP_SIZE = 128;
};

My compute shader is fairly simple:

#version 430 core

layout(std430, binding = 0) writeonly buffer SSBO {
    float data[];
};

layout(local_size_x = 128) in;

void main() {
    uint ident = gl_GlobalInvocationID.x;
    data[ident] = 5.0f;
}

When I read the buffer, most it is -1, but some of the data is comprised of random float values (-nan, 0, etc). What's going on here?

When resolving a symlink with boost the result doesn't equal the original path name

Windows 10
MS VS 2015
C++11
Boost 1.60

I create this symbolic link:

mklink /J "C:\T4 2.0\ApplicationSymlinks\T4" "C:\T4 2.0\Data"

This is a much simplified version of a program to check if the symbolic link is linked to the proper directory:

#include <boost/filesystem.hpp>
#include <iostream>
int main()
{
    boost::filesystem::path directory = "c:\\T4 2.0\\Data";

    boost::filesystem::path symlink = "c:\\T4 2.0\\ApplicationSymlinks\\T4";
    boost::filesystem::path path_linked_to("");
    path_linked_to = boost::filesystem::read_symlink(symlink);    // Resolve symlink. path_linked_to is not absolute. L"\\T4 2.0\\Data"
    path_linked_to = boost::filesystem::absolute(path_linked_to); // Absolute path. L"c:\\T4 2.0\\Data"

    if (directory == path_linked_to)
        std::cout << "paths are equal" << std::endl;
    else
        std::cout << "paths are not equal" << std::endl;                    
    return 0;
}

The output is "paths are not equal". Shouldn't they be equal? In the autos window of the debugger I do see this:

directory size 14 capacity 15

where as

path_linked_to size 16 capacity 23 because it includes two trailing '\0's.

These two trailing '\0's are introduced in read_symlink.

How do I resolve this? Why doesn't read_symlink return an absolute? Why does read_symlink add in two trailing '\0's (assuming that is the problem)? Why does operator== not ignore the '\0's?

How I compiled and linked:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\CL.exe /c /IC:\Libraries\boost_1_60_0 /ZI /nologo /W3 /WX- /sdl /Od /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Zc:inline /Fo"x64\Debug\\" /Fd"x64\Debug\vc140.pdb" /Gd /TP /errorReport:prompt resolvesymlilnk.cpp stdafx.cpp

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\x86_amd64\link.exe /ERRORREPORT:PROMPT /OUT:"c:\Users\Therefore\Documents\Visual Studio 2015\Projects\resolvesymlilnk\x64\Debug\resolvesymlilnk.exe" /INCREMENTAL /NOLOGO /LIBPATH:"C:\Libraries\boost_1_60_0\lib64-msvc-14.0" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /Debug /PDB:"c:\Users\Therefore\Documents\Visual Studio 2015\Projects\resolvesymlilnk\x64\Debug\resolvesymlilnk.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"c:\Users\Therefore\Documents\Visual Studio 2015\Projects\resolvesymlilnk\x64\Debug\resolvesymlilnk.lib" /MACHINE:X64 x64\Debug\resolvesymlilnk.obj

What is

I have this function call which I don't understand its syntax:

FunctionName<IS_SET_AUTO_REFERENCE>(Parameter1, Parameter2,Parameter3);

IS_SET_AUTO_REFERENCE sounds to be a Boolean but it is Not used anywhere neither defined.

Is this c++11 or c++? Is it related to the language? Google search shows other programmers using it with OpenCV but I still don't see What does IS_SET_AUTO_REFERENCE exactly serve here and how?