C++ struct testing - c++

Hi I am new to C++ and testing a structure in a c++ code in dev-c++. but it is not compiling and giving errors .
It is working well with .h extensions in pre-processor directives in dev-c++. so i Dont think so it carries .h extension problems
#include<iostream.h>
#include<conio.h>
#include<iomanip.h>
struct car
{
const int MAX=10;
char model[MAX];
char spare_part[MAX];
float cost;
}
int main()
{
car BMW ;
BMW.model[MAX]="SLR-8 S";
BMW.spare_part[MAX]="SILENCER";
BMW.cost=175.56F;
cout << setw(50) << "\n\n WELCOME TO SHOWROOM" << endl << endl;
cout << "CAR MODEL: " << BMW.model[MAX] << endl;
cout << "SPARE PART: " << BMW.spare_part[MAX] << endl;
cout << "COST OF PRODUCT: " << BMW.cost[MAX] << endl;
return 0;
}
Compiler logs are:
Compiler: Default compiler
Executing g++.exe...
g++.exe "D:\cdev\projects\structure.cpp" -o "D:\cdev\projects\structure.exe" -I"D:\cdev\Dev-Cpp\lib\gcc\mingw32\3.4.2\include" -I"D:\cdev\Dev-Cpp\include\c++\3.4.2\backward" -I"D:\cdev\Dev-Cpp\include\c++\3.4.2\mingw32" -I"D:\cdev\Dev-Cpp\include\c++\3.4.2" -I"D:\cdev\Dev-Cpp\include" -L"D:\cdev\Dev-Cpp\lib"
In file included from D:/cdev/Dev-Cpp/include/c++/3.4.2/backward/iostream.h:31,
from D:\cdev\projects\structure.cpp:1:
D:/cdev/Dev-Cpp/include/c++/3.4.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the <X> header for the <X.h> header for C++ includes, or <iostream> instead of the deprecated header <iostream.h>. To disable this warning use -Wno-deprecated.
D:\cdev\projects\structure.cpp:6: error: ISO C++ forbids initialization of member `MAX'
D:\cdev\projects\structure.cpp:6: error: making `MAX' static
D:\cdev\projects\structure.cpp:13: error: new types may not be defined in a return type
D:\cdev\projects\structure.cpp:13: error: extraneous `int' ignored
D:\cdev\projects\structure.cpp:13: error: `main' must return `int'
D:\cdev\projects\structure.cpp: In function `int main(...)':
D:\cdev\projects\structure.cpp:16: error: `MAX' undeclared (first use this function)
D:\cdev\projects\structure.cpp:16: error: (Each undeclared identifier is reported only
once for each function it appears in.)
Execution terminated

Values in stuct should be initialized in a constructor, or should be static. Like:
struct car
{
static const int MAX=10;
...
There is a semicolon missing after the struct definition. It should be like:
struct car
{
static const int MAX=10;
char model[MAX];
char spare_part[MAX];
float cost;
};

Check your semicolons. One is required after the closing } of the struct.
Also, declare the MAX variable static, i.e.
{
static const int MAX=10;
but the compiler tells you that one quite nicely...
And the third error comes from the fact that you declare MAX inside car, you'd have to reference it accordingly as car::MAX. But actually, the whole BMW.model[MAX]="SLR-8 S"; statement doesn't really make sense. That would mean 'assign the string "SLR-8 S" to the character after the last one in BMW.model' (for a char[MAX], the valid indices start at 0, and go to (MAX-1)!). Best use std::string instead of char model[MAX], that's by far easier to handle! E.g.:
struct car
{
std::string model;
Then you can simply say
BMW.model="SLR-8 S";

Related

Compiler error in introductory C++ example program [duplicate]

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 2 years ago.
I'm having some difficulty reproducing an example program of Object-Oriented Programming Using C++ described in "Encapsulation and Type Extensibility."
For simplicity's sake, I've cut out most of the code to focus on the specific error at hand:
#include <iostream> // Access standard IO library
#include <string> //Access type 'string'
using namespace std; //Use standard library namespace
const int max_length = 255;
class my_string {
public:
void assign(const char* st);
int length() const { return len; }
void print() const
{ cout << s << "\nLength: " << len << endl; }
private:
char s[max_length];
int len;
};
int main()
{
my_string one;
one.assign("I'm sorry Dave, I'm afraid I can't do that.");
one.print();
system("PAUSE");
}
When I try to compile, I get the error message:
[Linker error] undefined reference to 'my_string::assign(char const*)'
I'm not sure what I'm doing wrong. My best guess is that assign is incorrectly defined, since the main() block seems fine.
Edit:
The complete example as written in the book is:
In file string1.cpp
const int max_len = 255;
class my_string {
public:
void assign(const char* st);
int length() const { return len; }
void print() const
{ cout << s << "\nLength: " << len << endl; }
private:
char s[max_length];
int len;
};
int main()
{
my_string one, two;
char three[40] = {"My name is Charles Babbage."};
one.assign("My name is Alan Turing.");
two.assign(three);
cout << three;
cout << "\nLength: " << strlen(three) << endl;
if (one.length() <= two.length())
one.print();
else
two.print();
}
Linking and compiling errors are two different things. A compiler error means that you did something wrong in the syntax.
A linking error tells you that there is a part missing when the linker tries to put your program together.
[Linker error] undefined reference to 'my_string::assign(char const*)'
This error tells you that somewhere the promise was made to the compiler that my_string::assign(char const*) exists and can be used (by a declaration void assign(const char* st);). But in the linking step the linker cannot find that function.
If the error references a function that you have written, then you might have forgotten the definition of it or have mismatching signature between declaration and definition.
The compiler can't find it's definition.
Usually there is a header file (.h) where the class' declaration is put, including as less as possible and a source file (.cpp) that includes all the definitions.
The header file declarations tells the compiler which methods shall be available (as a promise),
the source file should contain the definition of the functions that are declared in the header file.
If they aren't defined, meaning there is no body for that function, it can't be executed. In your book, the code is both declared and defined, by writing the methods inside the class' definition.
You could do the same:
public:
void assign(const char* st) {
/* implementations of the assign method here
(or leave it empty for this example, but rather don't)*/
};
int length() const { return len; };
...

C++ handles an uninitialized field in a strange way

The sample below shows reading an uninitialized field a.i1 in two ways. The first call does not compile. However, calling a.donothing() that does not do anything, the original call compiles fine and prints the default value 0. Why is this inconsistency?
I am using Visual Studio Community 2015, the compiler output is as follows:
Severity Code Description Project File Line Suppression State
Error C4700 uninitialized local variable 'a' used
class A {
public:
int i1;
void donothing() {}
};
int main() {
A a;
cout << "main1: " << a.i1 << endl; // compile fails
a.donothing();
cout << "main2: " << a.i1 << endl; // prints 0 (default)
return 0;
}
Compiler is doing what it ought to do. You can fix it like this (as one solution out of many):
class A {
public:
A(int i = 0) : i1(i) {}
int i1;
void donothing() {}
};
In both cases a warning must be issued, at most. The fact that calling donothing cancels the error is a clear indication that this is a bug. You can report it at Microsoft Connect.
A simple workaround for this problem is to change the declaration to A a{};.
You can test your code on different compilers at Compiler Explorer.
[EDIT] The warning message C4700 is treated as an error if Security Development Lifecycle is turned on (/sdl).
Depends on the compiler, the compiler should supply a default constructor that will initialize your members with a default value. But this behavior is not dependable. Since C++11 you can say ClassName()=default; The best practice is to prove your own default constructor.
Your code never had any compiler errors with g++ 5.4.0
#include <iostream>
using namespace std;
class A {
public:
//A() : i1(0) { } // compiler will provide this if you don't write anything
// since C++ 11 you can also say A() = default;
A() = default;
int i1;
void donothing() {}
void writeMember() const { cout << "i1 value: " << i1 << endl; }
};
// better provide a signature for the main function
int main(int argc, char* argv[]) {
A a;
a.writeMember();
cout << "main1: " << a.i1 << endl; // compile fails
a.donothing();
cout << "main2: " << a.i1 << endl; // prints 0 (default)
return 0;
}
To compile the above code stored in testclass.cpp
g++ -std=c++11 -o testclass testclass.cpp
By using the C++11 default I got
i1 value: 4196976
main1: 4196976
main2: 4196976
If you comment out A()=default; this will rely on the compiler provided initializer, or the compiler may be lazy and not doing anything for performance reasons. You get
i1 value: 4196944
main1: 4196944
main2: 4196944
If you uncomment the line after public: you should consistently get 0
This illustrates the importance of adhering to good conventions of alway provide your own default constructor. The compiler maybe doing the right thing by not assigning any particular value to your member because you may assign another value in the next operation. This can save one operation. The member will be simply allocated on the stack, in that case the member got a random value. If you run this code on a different computer you will for sure get a different value.

C++ compiler not throwing error for undeclared variable

I tried to search for this specific problem and did not find anythying concrete.
I was using an undeclared variable in my program and the compiler did not complain, it just gave a warning and the program runs fine. My gcc version is 4.1.2
Below is a sample program I wrote to reproduce this, the variable "index" is not declared, why is the compiler treating "index" as a function and where does it find the definition of the function?
#include <iostream>
using namespace std;
int testfunction()
{
try {
cout << "inside testfunction method\n";
return 2;
} catch(...) {
cout << "caught exception" << index << endl;
}
return 1;
}
int main()
{
cout << "Testfunction return value : " << testfunction() << endl;
}
Compiling:
~ g++ throwreturntest.cpp
throwreturntest.cpp: In function ���int testfunction()���:
throwreturntest.cpp:11: warning: the address of ���char* index(const char*, int)���, will always evaluate as ���true���
Running :
~ ./a.out
inside testfunction method
Testfunction return value : 2
Looks like index is the name of a GCC builtin function:
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
So it is already declared, just not by you.
The compiler is quite verbose about the situation. It things that index is an address of a function with signature
char *index(const char *s, int c);
See man index(3). The corresponding header is somewhere in the chain of <iostream>

Questions about C++ Preprocessor

I am learning C++ macro. And now I am totally confused. So help me! Below is my code, what I am trying to do is to use the C++ macro and call different functions using "template" such that I could only write one function and this function can be used to do the same things for different types. But when I compile this code, it throws the following errors.
testCPP.cpp: In function 'void test_int_Macro(int)':
testCPP.cpp:14: error: a function-definition is not allowed here before '{' token
testCPP.cpp:26: error: expected `}' at end of input**
#include<iostream>
#include<cstdint>
using namespace std;
#define Query_Data(Type)\
void test_##Type##_Macro(Type data){ \
cout<<"Test: "<<sizeof(data)<<" "<<endl; \
//cout<<"Type is "<<##Type##<<endl;\
}
Query_Data(int)
Query_Data(char)
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
Query_Data(num);
//Query_Data(c);
}
In C++, macros are very simple and stupid. The proeprocessor simply regurgitates whatever the macro is defined to be wherever you invoke it.
If you do the preprocessing on a piece of paper, what you come up with is:
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
void test_num_Macro(Type data){
cout<<"Test: "<<sizeof(data)<<" "<<endl;
//cout<<"Type is "<<##Type##<<endl;
}
}
The compiler gave you an error message which in this case was spot-on:
testCPP.cpp:14: error: a function-definition is not allowed here before '{' token
Look at the main function you end up with as a result of the preprocessing. It has a function declared within it. That, obviously, isn't allowed.
Now, if we follow this train of thought to the next logical stage, the question becomes "so how do I achieve what I'm trying to achineve?"
You said that:
what I am trying to do is to use the C++ macro and call different
functions using "template" such that I could only write one function
and this function can be used to do the same things for different
types.
And there is a facility in C++ for exactly this. Coincidentally, they are called templates. Here's how you might use one here:
template <typename Val>
void test ()
{
cout << "Test: " << sizeof (Val) << " " << endl;
}
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
test <char> ();
test <int> ();
}
Macros are a cludge. The are not sophisticated, they skirt around the C++ type system, they are very hard to debug and maintain. It is generally advised to avoid using them unless you have no other choice. There are places when you do have no other choice -- but this isn't one of them.
John Dibling is quite right. But I would like to point out that the easiest way to debug preprocessor issues is usually by running g++ -E src.cpp which shows you the file after it's been preprocessed. (remove your #include's first or you'll get way too much output)
And the reason for the the "expects '}' at end of input" error is that commented line in your macro. The preprocessor treats it as an empty line (without a trailing ) and so doesn't look farther and leaves your '}' out of the define.
You should avoid using the preprocessor in C++ for anything but #include and include guards in header files.
Macros are simple text replacement snippets, so you will end up defining those functions inside main function, a thing you cannot do in C++. You can see it very well if you run your code through the preprocessor:
void test_int_Macro(int data){ cout<<"Test: "<<sizeof(data)<<" "<<endl;
void test_char_Macro(char data){ cout<<"Test: "<<sizeof(data)<<" "<<endl;
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
void test_num_Macro(num data){ cout<<"Test: "<<sizeof(data)<<" "<<endl;;
}
Thus said, you should (and probably, you already got it) use templates:
template <class Type>
void Query_Data(Type data) {
std::cout << "Test: " << sizeof(data) << " " << std::endl;
}
If you wish, you can specialize the template for specific types like:
template<>
void Query_Data<int>(int data) {
std::cout << "This is an integer!" << std::endl;
}
and use them as intended:
int main(){
cout<<sizeof(unsigned)<<endl;
cout<<sizeof(char)<<endl;
cout<<sizeof(int32_t)<<endl;
int num=6;
char c='a';
Query_Data(num);
Query_Data(c);
}

C++ templates problem

I am new to templates in c++.
i was trying some small programs.
CPP [80]> cat 000001.cpp 000001.hpp
#include <iostream>
#include <string>
#include "000001.hpp"
int main()
{
int i = 42;
std::cout << "max(7,i): " << ::max(7,i) << std::endl;
double f1 = 3.4;
double f2 = -6.7;
std::cout << "max(f1,f2): " << ::max(f1,f2) << std::endl;
std::string s1 = "mathematics";
std::string s2 = "math";
std::cout << "max(s1,s2): " << ::max(s1,s2) << std::endl;
}
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
when i compile this program:
i get an error below:
CPP [78]> /opt/aCC/bin/aCC -AA 000001.cpp
Error (future) 229: "/opt/aCC/include_std/string.cc", line 164 # "Ambiguous overloaded function call; a
function match was not found that was strictly best for ALL arguments. Two functions that matched
best for some arguments (but not all) were "const unsigned long &max<unsigned long>(const unsigned
long &,const unsigned long &)" ["000001.hpp", line 2] and "const unsigned long &std::max<unsigned
long>(const unsigned long &,const unsigned long &)" ["/opt/aCC/include_std/algorithm", line 1762]."
Choosing "const unsigned long &max<unsigned long>(const unsigned long &,const unsigned long &)"
["000001.hpp", line 2] for resolving ambiguity.
_C_data = _C_getRep (max (_RW::__rw_new_capacity (0, this),
^^^
Warning: 1 future errors were detected and ignored. Add a '+p' option to detect and fix them before they become fatal errors in a future release. Behavior of this ill-formed program is not guaranteed to match that of a well-formed program
Could nybody please tell me what exactly the error is?
You are probably including <iostream.h> instead of <iostream> somewhere. The former hasn't existed for some time now, but for compatibility reasons, you compiler still accepts the include and replaces it with
#include <iostream>
using namespace std;
This causes std::max to be brought to the global namespace, thus resulting in an ambiguity. Replace <iostream.h> with <iostream> or rename your max function and the problem should disappear.
Edit: You've apparently fixed the include, but I bet you still have using namespace std; somewhere. You need to get rid of that. In fact you should never use using namespace in the global scope.
Edit: You might also have using std::max somewhere. You need to get rid of it too.
The code you've posted compiles just fine, there must be something else that is wrong inside "000001.hpp". Can you post the contents of that file too?
Edit: If you do as avakar says but the problem persists, that must be due to some problem with your compiler. There are two obvious workarounds I can think of: rename your max function to something else, or put it in a namespace:
namespace Foo
{
template <typename T>
inline T const& max (T const& a, T const& b)
{
return a < b ? b : a;
}
}
int main()
{
int i = 42;
std::cout << "max(7,i): " << Foo::max(7,i) << std::endl;
double f1 = 3.4;
double f2 = -6.7;
std::cout << "max(f1,f2): " << Foo::max(f1,f2) << std::endl;
std::string s1 = "mathematics";
std::string s2 = "math";
std::cout << "max(s1,s2): " << Foo::max(s1,s2) << std::endl;
}
I don't know which compiler you are using but the second error tells you that the two following functions are clashing :
::max
std::max
It seems really weird, you may have a using namespace std; somewhere or worse, that one of your include use iostream.h as noted in the first error. Could you give more information about your compiler/toolchain and the content of your .hpp file?
It says that two definitions for
max<unsigned long>
were found. One definition is in 000001.hpp and the other is in /opt/aCC/include_std/algorithm. The compiler chose the one in 000001.hpp for now, so no error is present now. But it says that these two definitions may cause errors in the future.
I don't know if this causes the problem, but anyhow; you shouldnt use the name max for your global (or local) function as it is a part of STL.