I have a problem with making a program that uses winbgim.h header file. It is a simple program that makes just one simple circle. I am currently learning about winbgim and graphics.h libraries. I downloaded it, I downloaded the library and included it in Codeblocks following this and it works properly.
But when I try to use it, another code pops out and on the 302nd line it stands "error: redefinition of "int right". I am making this in a console file in Codeblocks IDE.
Can anyone help? Here is my code:
#include <iostream>
#include <winbgim.h>
#include <cstdlib>
using namespace std;
int main()
{
int gdriver = 9;
int gmode = 2;
initgraph(&gdriver,&gmode, "");
setbkcolor(WHITE);
setcolor(BLACK);
cleardevice();
circle(320,240,180);
getch();
closegraph();
return 0;
}
I don't know whether it suits this forum or not but I just wanted to tell (the world) something. I recently decided to try out WinBGIm library, so I downloaded the package and after setting up all the compiler and linker settings, ran my simple "Hello World" Code. But I got the following message from my compiler (MinGW, CodeBlocks IDE).
d:\codeblocks\mingw\bin..\lib\gcc\mingw32\4.4.1........\include\graphics.h|302|error:
redefinition of 'int right'|
d:\codeblocks\mingw\bin..\lib\gcc\mingw32\4.4.1........\include\graphics.h|302|error:
'int right' previously declared here|
||=== Build finished: 2 errors,
0 warnings ===|
After having googled the problem I found out nothing (If you don't count a suggestion to use CodeBlocks-EP as a Solution).
As I was taking a look at the header files, I found the problem (yeah!!!)
The problem was with the function printimage.
The original declaration was
//The original declaration. Note that there are two "right" variables
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int right=0, int right=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
So what I did is that, I simply changed one of the "right" (the later former one) variable to "top". That's it.
//The corrected code
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int top=0, int right=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
I did the same thing as #Puneet suggested, just change the name of one of the variables named "right".
The thing that I want to add is that you can't change the name within codeblocks (at least I couldn't do it, the changes were ignored). So I suggest you save your code file/s, close the IDE, and open the "graphics.h" file with a text editor, change the name, save, and you are all set.
You can find your MinGW directory by opening a new codeblocks project, right click in the <iostream> and select something like open file, which will open the header in a new codeblocks "tab", right click the tab and click open containing folder. Thats it.
Related
I have been recently practicing managing multiple objects and drawing them in C++ using SFML library. I wanted my textures and future resources to be more reusable so I decided to make use of Thor library which suits my needs really well.
So I've written first few lines of code based on what you can find in this tutorial and the compiler always says:
main.cpp|12|error: 'textures_holder' does not name a type
This line gives an error :
textures_holder.acquire("Dirt", thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png"));
I'm using Code::Blocks IDE with MinGW compiler and SFML 2.5.0.
Here's my main.cpp and the header file which contains extern object :
//...
#include <Thor/Resources.hpp>
#include "Dirt_Block.h"
using namespace std;
//Adding textures to the texture library
//THIS LINE GIVES AN ERROR
textures_holder.acquire("Dirt", thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png"));
//Rest of code...
Dirt_Block.h (only the upper part) :
#ifndef DIRT_BLOCK_H
#define DIRT_BLOCK_H
#include <SFML\Graphics.hpp>
#include <vector>
#include <Thor/Resources.hpp>
#include <Thor/Resources/SfmlLoaders.hpp>
extern sf::Vector2u screenRes;
extern thor::ResourceHolder<sf::Texture, std::string> textures_holder;
//Rest of the code
I'd like to know what is causing this error and maybe help others who may experience similiar frustrating problems. Thanks for help.
EDIT :
As suggested in the comment I've declared a few extern int variables in the Dirt_Block.h so now it looks like this :
//...
extern int test_int_up;
extern sf::Vector2u screenRes;
extern thor::ResourceHolder<sf::Texture, std::string> textures_holder;
extern int test_int_d;
//...
And then assinged to them some value in main.cpp :
//...
test_int_up = 55;
test_int_d = 55;
//Adding textures to the texture library
textures_holder.acquire("Dirt", thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png"));
//...
But the compiler gives error :
main.cpp|9|error: 'test_int_up' does not name a type
main.cpp|10|error: 'test_int_d' does not name a type
main.cpp|12|error: 'textures_holder' does not name a type
Much less distracting to see what your problem is without all the extraneous code!
C++ programs don't start from the top of the file and run code down to the bottom. They start at the main(), and control flow proceeds from there, with one thing triggering another.
(Note: That doesn't take into account global constructor ordering, which does go in order of declaration--but you have no guarantee of the order declarations from "different files" might run in.)
Point being, you can't just make random function or method calls in the middle of a file. That's where you put declarations. You have to be inside of a function or method to make calls, e.g.
int main() {
textures_holder.acquire(
"Dirt",
thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png")
);
...
}
When I try to compile the following C code on Visual Studio 2017 with default C/C++ settings:
#include <stdio.h>
#include <stdlib.h>
/* function declaration */
/*Line 6*/ int max(int num1, int num2, int num3);
int main() {
/* local variable definition */
int a = 100;
int b = 200;
int c = 400;
int ret;
/* calling a function to get max value */
ret = max(a, b, c);
printf("Max value is : %d\n", ret);
return 0;
}
/* function returning the max between two numbers */
/*Line 25*/ int max(int num1, int num2, int num3) {
/* local variable declaration */
int result;
if (num1 > num2)
result = num1;
else
result = num3;
return result;
}
I get the error(s):
Expected an Identifier: Line(s) 6,25
Expected a ";": Line(s) 25
Intellisense highlights those lines and wont let me run the code. Yet in Codeblocks (Using the default GNU GCC compiler, from mingW) this EXACT code compiles just fine. What is causing this?
Multiple sources have told me that its not due to Codeblocks using GCC compiler
and Visual Studio using "cl" compiler by default.
The same sources have told me that it is also not due to the possibility of each IDE compiling the code using different C standards.
I have named the the file extension as ".c" and I get these errors
If I try to compile the code as c++(or as a ".c++" file it works, but that's not what I want.
I want C.
I would prefer to use Visual Studio over Codeblocks due to its sleek look and menu layout. I also prefer the Visual Studio debugger.
What steps can I take to successfully compile this simple code on Visual Studio 2017?
Microsoft has a notoriously defined max macro. If the macro definition is pulled into your source for whatever reason, token substitution will wreak havoc. The result of that I'd wager is what you are seeing. Mostly because by your own admission, it happens only in Visual Studio.
The solution (and test for it) is fairly simple. One of these should "fix" your code:
Rename max to something else, like my_max.
Before including any headers, add #define NOMINMAX to suppress the definition of the macros in any included MS headers.
Beyond that you are gonna have to tinker with your project settings and see what may be improperly set. This is not a macro that should be automatically added in a simple console project.
I know Turbo C++ is oudated as hell, but so is the curriculum of our central board in my country (India). And I am doing a school project. And I don't have the freedom to choose my own IDE and compiler. Go figure.
NOTE: I am using Turbo C++ 3.0 in DOSBox in Win10
Anyway, here is the project directory I made to test TC++'s linking:
TC/BIN
-MAIN.CPP
#include <iostream.h>
#include <conio.h>
#include "CL.H"
int main()
{
clrscr();
cout<<"HW";
cl c;
c.set(5);
cout<<c.get();
getch();
return 0;
}
-CL.CPP
#include "CL.H"
void cl::set( int i )
{
a = i;
}
int cl::get()
{
return a;
}
-CL.H
#ifndef CL_H
#define CL_H
class cl
{
int a;
public:
void set( int i);
int get();
};
#endif
All of these compile fine. Upon trying to link, I get the following linker error:
LINKER ERROR: Undefined symbol cl::get() in module MAIN.CPP
LINKER ERROR: Undefined symbol cl::set( int ) in module MAIN.CPP
You can do that:
1- Open TC.exe
2- From project select Open Project
3- Enter the name of project eg: MyProj.prj and Press ok.
4- From project select Add item
5- Locate all the source files and add them.
6- compile and build.
(Posted on behalf of the question author).
I had the .h files also added to the project. That caused all the trouble. Removing the .h files from the project seems to make it work.
I need to use BGI graphics in my program and it worked just fine in the wxDevCpp 7.3. But now I installed an updated version of this IDE 7.4, did everything by instruction http://www.cs.colorado.edu/~main/bgi/dev-c++/, just like before, but now when I try to compile any simple program like
#include <graphics.h>
int main( )
{
initwindow(400, 300, "First Sample");
circle(100, 50, 40);
while (!kbhit( ))
{
delay(200);
}
return 0;
}
I get multiple errors saying that
initwindow(), circle(), kbhit(), delay()
were not declared in the scope. I have no idea what to do.
The change in updated wxDevCpp is the different folder structure, but I copypasted the graphics.h and libbgi.a in several folders. I did not forget to add the linker commands just as the instruction said, but it does not work.
Also, I found another graphics.h which came along with installation of new wxDevCpp and though it might bring a conflict, so I just removed it. No change :(
I think I solved it! It was actually trouble with the graphics.h
When I copypasted all the graphics.h into my .cpp, the compiler gave an error that int right was declared twice in the following code:
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int right=0, int right=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
redefinition of int right, so as it is just a prototype, I change it to:
void printimage(
const char* title=NULL,
double width_inches=7, double border_left_inches=0.75, double border_top_inches=0.75,
int left=0, int right=0, int=INT_MAX, int bottom=INT_MAX,
bool active=true, HWND hwnd=NULL
);
Now it works!!!
I'm trying to write a header-only library of helper functions for myself. (I'm using boost and SDL, and boost is much easier to use, so I want to emulate that for my own helper library.)
I'm getting the error "Does not name a type" for one of my classes, and it's confusing me. I know I can get this problem with a misspelling or circular include, but can't find either of those problems in my code. Forward declaration in SdlWindow.cpp doesn't help. Including the header again (so I /do/ have a circular include) doesn't help either (I get "previously defined" errors).
Main.cpp:
#include <WBS/SdlWindow.hpp>
int main(int argc, char **argv) {
WBS::SdlWindow myWindow("Test window", 640, 480);
return 0;
}
SdlWindow.hpp:
#ifndef SDLWINDOW_HPP_
#define SDLWINDOW_HPP_
#include <string>
#include <SDL/SDL.h>
namespace WBS {
class SdlWindow {
public:
//Member Variables
SDL_Surface *screen;
int xSize;
int ySize;
//Constructor and Destructor
SdlWindow(std::string title, int xSize, int ySize);
virtual ~SdlWindow();
//Member Functions
};
}
#include "SdlWindow.cpp"
#endif /* SDLWINDOW_HPP_ */
And SdlWindow.cpp:
#include <string>
namespace WBS {
SdlWindow::SdlWindow(std::string title, int xSize, int ySize) {
this->xSize = xSize;
this->ySize = ySize;
SDL_Init(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(xSize, ySize, 32, SDL_ANYFORMAT);
SDL_WM_SetCaption("Simple Window", "Simple Window");
}
SdlWindow::~SdlWindow() {
SDL_FreeSurface(screen);
SDL_Quit();
}
}
The error I get is "SdlWindow' does not name a type", in SdlWindow.cpp, where I declare the two SdlWindow functions. What's causing this and how can I fix it?
I'm compiling with mingw32's gcc in Eclipse on Windows Vista.
I see what you are trying to do: a header-only library implies that .cpp file is included into .h file and not the other way around (this is, of course, confusing for many people). But if you are doing it that way, then you should not attempt to compile your .cpp files as ordinary source files. In fact, it might be a better idea to give your .cpp file a different extension: a .hpp maybe, for one example.
I suspect that you somehow managed to make SdlWindow.cpp a part of your project, i.e. you are trying to compile your SdlWindow.cpp by itself, as an ordinary source file. This will not work for obvious reasons. If your are trying to implement a header-only library, then no files from that library should be compiled as ordinary source files.
Of course, on an additional note, this whole thing will not work the way it looks now. A header-only library cannot contain non-inline non-template functions. It works for Boost because in Boost the functions are templates. Your functions are not templates. You have to declare them inline then, or otherwise you'll end up with multiple-definition errors for each of your functions.
You need to #include <WBS/SdlWindow.hpp> from SdlWindow.cpp.
You need to include WBS/SdlWindow.hpp from SdlWindow.cpp, as Sam said, but also you do not need to include SdlWindow.cpp from its header (that's a Bad Thing waiting to happen).