Accessing Functions from Other Files

I am having trouble accessing my 'GLCheck' function from outside the file it is defined within.

If I put functions in separate .h file - 'Overload':
I have to include Shader.h in the Overload.h file so that the compiler can find the definition of the Shader class. I also have to include the Overload.h file in the Shader.h file so that the Overload.h functions can be accessed from Shader.h. This creates all sorts of errors so the route cause of the problem is not obvious, but it seems to me that the reason for the errors stems from the fact that Shader.h is included in Overload.h and Overload.h is included in Shader.h (circular inclusion).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Main.cpp
//--------------------------------
#include <iostream>
#include "Shader.h"
#include "Errors.h"
#include "Overload.h"

int main()
{
	unsigned int x{ 1 }, y{ 2 };
	Shader shader;
	GLCheck(&Shader::Bind, shader); // works fine
	GLCheck(&Shader::AttachShaders, shader, x, y); // works fine
}
//--------------------------------

// Shader.h 
//--------------------------------
#pragma once
#include "Overload.h"

class Shader
{
public:
	Shader()
	{
		// create shader, etc..
		unsigned int x{ 1 }, y{ 2 };
		GLCheck(&Shader::AttachShaders, this, x, y); // 'GLCheck': identifier not found
		GLCheck(&Shader::Bind, this); // 'GLCheck': identifier not found
	}

	void AttachShaders(unsigned int& vertex_shader, unsigned int& fragment_shader)
	{
		// attach shaders
	}

	void Bind() const
	{
		// bind shader
	}
};
//--------------------------------

// Overload.h 
//--------------------------------
#pragma once
#include "Shader.h"
#include "Errors.h"

typedef void (Shader::* void_uir_uir) (unsigned int&, unsigned int&);
void GLCheck(void_uir_uir Function, Shader& object, unsigned int& vertex_shader, unsigned int& fragment_shader)
{
	ClearErrors();
	(object.*Function) (vertex_shader, fragment_shader);
	CheckErrors();
}

typedef void (Shader::* void__const) () const;
void GLCheck(void__const Function, Shader& object)
{
	ClearErrors(); // clear pre-existing errors
	(object.*Function) (); // call passed function
	CheckErrors();
}
//--------------------------------

// Errors.h
//--------------------------------
#pragma once

void ClearErrors()
{
	// clear pre-existing errors...
}

void CheckErrors()
{
	// check for errors...
}
//-------------------------------- 


If I put functions in main():
The functions can be accessed in main() but cannot be accessed from another file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Main.cpp
//--------------------------------
#include <iostream>
#include "Shader.h"
#include "Errors.h"

typedef void (Shader::* void_uir_uir) (unsigned int&, unsigned int&);
void GLCheck(void_uir_uir Function, Shader& object, unsigned int& vertex_shader, unsigned int& fragment_shader)
{
	ClearErrors();
	(object.*Function) (vertex_shader, fragment_shader);
	CheckErrors();
}

typedef void (Shader::* void__const) () const;
void GLCheck(void__const Function, Shader& object)
{
	ClearErrors(); // clear pre-existing errors
	(object.*Function) (); // call passed function
	CheckErrors();
}

int main()
{
	unsigned int x{ 1 }, y{ 2 };
	Shader shader;
	GLCheck(&Shader::Bind, shader); // works fine
	GLCheck(&Shader::AttachShaders, shader, x, y); // works fine
}
//--------------------------------

// Shader.h
//--------------------------------
#pragma once

class Shader
{
public:
	Shader()
	{
		// create shader, etc..
		unsigned int x{ 1 }, y{ 2 };
		GLCheck(&Shader::AttachShaders, this, x, y); // 'GLCheck': identifier not found
		GLCheck(&Shader::Bind, this); // 'GLCheck': identifier not found
	}

	void AttachShaders(unsigned int& vertex_shader, unsigned int& fragment_shader)
	{
		// attach shaders
	}

	void Bind() const
	{
		// bind shader
	}
};
//--------------------------------

// Errors.h
// file identical to initial definition of Errors.h 


If I put functions at the top of Shader.h file (above Shader class):
Again there are so many errors that it is hard to tell what the route problem is. Maybe it is that I am referring to a Shader type in the typedef and the overload function parameters before the compiler is actually aware of the Shader class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Main.cpp
//--------------------------------
#include <iostream>
#include "Shader.h"
#include "Errors.h"

int main()
{
	unsigned int x{ 1 }, y{ 2 };
	Shader shader;
	GLCheck(&Shader::Bind, shader); // red squiggly line under 'GLCheck' 
	GLCheck(&Shader::AttachShaders, shader, x, y); // red squiggly line under 'GLCheck' 
}
//--------------------------------

// Shader.h
//--------------------------------
#pragma once

typedef void (Shader::* void_uir_uir) (unsigned int&, unsigned int&);
void GLCheck(void_uir_uir Function, Shader& object, unsigned int& vertex_shader, unsigned int& fragment_shader)
{
	ClearErrors();
	(object.*Function) (vertex_shader, fragment_shader); // red squiggly line under 'Function' 
	CheckErrors();
}

typedef void (Shader::* void__const) () const;
void GLCheck(void__const Function, Shader& object) // red squiggly line under 'void__const' 
{
	ClearErrors(); 
	(object.*Function) (); // red squiggly line under 'Function' 
	CheckErrors();
}

class Shader
{
public:
	Shader()
	{
		// create shader, etc..
		unsigned int x{ 1 }, y{ 2 };
		GLCheck(&Shader::AttachShaders, this, x, y); // red squiggly line under 'GLCheck' 
		GLCheck(&Shader::Bind, this);  // red squiggly line under 'GLCheck' 
	}

	void AttachShaders(unsigned int& vertex_shader, unsigned int& fragment_shader)
	{
		// attach shaders
	}

	void Bind() const
	{
		// bind shader
	}
};
//--------------------------------

// Errors.h
// file identical to initial definition of Errors.h 


If I put functions at the bottom of Shader.h file (below Shader class):
When I call the functions inside the Shader class, the compiler isn't able to identify the functions since they are at the bottom of the file so the compiler is unaware of their existence.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Main.cpp
//--------------------------------
#include <iostream>
#include "Shader.h"
#include "Errors.h"

int main()
{
	unsigned int x{ 1 }, y{ 2 };
	Shader shader;
	GLCheck(&Shader::Bind, shader); 		
	GLCheck(&Shader::AttachShaders, shader, x, y); 
}
//--------------------------------

// Shader.h
//--------------------------------
#pragma once

class Shader
{
public:
	Shader()
	{
		// create shader, etc..
		unsigned int x{ 1 }, y{ 2 };
		GLCheck(&Shader::AttachShaders, this, x, y); // red squiggly line under 'GLCheck' 
		GLCheck(&Shader::Bind, this); // red squiggly line under 'GLCheck' 
	}

	void AttachShaders(unsigned int& vertex_shader, unsigned int& fragment_shader)
	{
		// attach shaders
	}

	void Bind() const
	{
		// bind shader
	}
};

typedef void (Shader::* void_uir_uir) (unsigned int&, unsigned int&);
void GLCheck(void_uir_uir Function, Shader& object, unsigned int& vertex_shader, unsigned int& fragment_shader)
{
	ClearErrors();
	(object.*Function) (vertex_shader, fragment_shader);
	CheckErrors();
}

typedef void (Shader::* void__const) () const;
void GLCheck(void__const Function, Shader& object)
{
	ClearErrors();
	(object.*Function) ();
	CheckErrors();
}
//--------------------------------

// Errors.h
// file identical to initial definition of Errors.h 

TL;DR - how can I access this function from both the file in which it is situated and also a separate file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
typedef void (Shader::* void_uir_uir) (unsigned int&, unsigned int&);
void GLCheck(void_uir_uir Function, Shader& object, unsigned int& vertex_shader, unsigned int& fragment_shader)
{
	ClearErrors();
	(object.*Function) (vertex_shader, fragment_shader);
	CheckErrors();
}

typedef void (Shader::* void__const) () const;
void GLCheck(void__const Function, Shader& object)
{
	ClearErrors(); // clear pre-existing errors
	(object.*Function) (); // call passed function
	CheckErrors();
}
Last edited on
Consider what happens when main.cpp does #include "Shader.h" at line 4:
The preprocessor sees:
1
2
#pragma once
#include "Overload.h" 

Now it goes to Overload.h and sees:
1
2
#pragma once
#include "Shader.h" 

It goes back to Shader.h and sees
#pragma once
So it stops processing Shader.h and continues in Overload.h:

typedef void (Shader::* void_uir_uir) (unsigned int&, unsigned int&);
This might generate an error because it doesn't have the definition of Shader.

Even if the compiler gets through that, you'll end up with multiple definitions of the functions in the header files if you have more than one .cpp files that includes them. Never define functions in a header file unless they are inline.

To fix this problem, just put the code of these functions in separate .cpp files:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Main.cpp
//--------------------------------
#include <iostream>
#include "Shader.h"
#include "Errors.h"
#include "Overload.h"

int
main()
{
    unsigned int x {1}, y{2};
    Shader shader;
    GLCheck(&Shader::Bind, shader);		 // works fine
    GLCheck(&Shader::AttachShaders, shader, x, y); // works fine
}

//--------------------------------
// Shader.h 
//--------------------------------
#pragma once

class Shader
{
public:
    Shader();
    void AttachShaders(unsigned int &vertex_shader, unsigned int &fragment_shader);
    void Bind() const;
};

//--------------------------------
// Shader.cpp
//--------------------------------
#include "Shader.h"
#include "Overload.h"

Shader::Shader()
{
    // create shader, etc..
    unsigned int x{1}, y{2};
    GLCheck(&Shader::AttachShaders, this, x, y); // 'GLCheck': identifier not found
    GLCheck(&Shader::Bind, this);		 // 'GLCheck': identifier not found
}

void
Shader::AttachShaders(unsigned int &vertex_shader, unsigned int &fragment_shader)
{
    // attach shaders
}

void
Shader::Bind() const
{
    // bind shader
}

//--------------------------------

// Overload.h 
//--------------------------------
#pragma once
#include "Shader.h"
#include "Errors.h"

typedef void (Shader::*void_uir_uir) (unsigned int &, unsigned int &);
void GLCheck(void_uir_uir Function, Shader & object, unsigned int &vertex_shader,
	     unsigned int &fragment_shader);

typedef void (Shader::*void__const) () const;
void GLCheck(void__const Function, Shader & object);

//--------------------------------
// Overload.cpp
//--------------------------------
void GLCheck(void_uir_uir Function, Shader & object, unsigned int &vertex_shader,
	     unsigned int &fragment_shader)
{
    ClearErrors();
    (object.*Function) (vertex_shader, fragment_shader);
    CheckErrors();
}

void GLCheck(void__const Function, Shader & object)
{
    ClearErrors();				 // clear pre-existing errors
    (object.*Function) ();			 // call passed function
    CheckErrors();
}

//--------------------------------

// Errors.h
//-------------------------------- 

Thanks dhayden
Topic archived. No new replies allowed.