I'm doing a course but the things the lecturer says works don't - visual-studio

I have recently gotten into programming and decided to learn C++. I took advantage of the sale on Udemy and bought three courses there, one for beginners on C++, one for game-making and one for Blender.
I started doing the course for beginners, the lecturer said that he would use Code::Blocks but that any other IDE would be fine so I downloaded Visual Studio 2017 because that's what the game-making course used. But when I do exactly as the lecturer says (and writes), the code won't compile correctly.
Here is an example:
What the lecturer wrote and got to work on his computer
#include <iostream>
using namespace std;
main()
{
cout << "Hello world! :-)";
}
What I figured out would work after some googling
#include <pch.h>
#include <iostream>
using std::cout;
int main()
{
cout << "Hello world! :-)";
}
And my question to those who are experienced is: What is the difference between Code::Blocks and Visual Studio 2017? What is different in that case? Will I even be able to use this course to learn?
Thanks in advance!
edit: edited in a missing # in the lecturer's code

#include <pch.h>:
See Gabriel's answer.
include <iostream> vs #include <iostream>:
The former is plain wrong. It has to be #include with the #.
using namespace std; vs using std::cout;:
While neither is particularly good practice, both should do the same thing here. If you write neither of them, you will have to write std::cout << ... instead of only cout << ... - that seems annoying but is something you should get used to if you want to eventually be a serious C++ programmer. See also Why is "using namespace std" considered bad practice?.
main() vs int main():
This is not something that Code::Blocks should allow because it is not correct C++. main should always return int.
Overall you seem to have hit an unfortunate number of differences between environments/compilers on this basic example already. However, neither your course nor VS2017 is wrong so far, so I recommend you keep using them. If something that your lecturer writes won't work for in a different environment, it's probably a bad idea to write that kind of code in the first place. And they did make several mistakes in this simple example.
PS: I strongly recommend enabling warnings, because they may tell you when you do something wrong in a more subtle way. There are many mistakes (of the "shooting yourself in the foot" kind) that the compiler is not required to stop you from making, but if you ask to be stopped (by heeding warnings) it will help you.

Using Visual Studio should be okay as long as you disable precompiled headers and your tutorial uses standard-compliant code.
About precompiled headers :
Visual Studio enables pre-compiled headers by default in a C++ command line program. This means that in your project, it'll by default force you to use a precompiled header in the first line of your source code (pch.h here).
By disabling them, you can almost* make the first snippet work in VS. To do this, select your project, go to the "Project->Properties" menu, then to the "Configuration Properties -> C/C++ -> Precompiled Headers" section, then change the "Precompiled Header" setting to "Not Using Precompiled Headers" option (this applies to VS 2012, applying this to other versions of VS should be easy).
If you want to avoid this in the future, you can create an empty project when setting up your project in VS.
See also : http://msdn.microsoft.com/en-us/library/h9x39eaw%28v=vs.71%29.aspx, How to avoid precompiled headers
* : The first snippet won't actually work since the declaration of main is not correct C++, only C (see https://en.cppreference.com/w/cpp/language/main_function, What is the proper declaration of main?)

To your actual question, VS will be fine for your course, although I'm still puzzled by the lecturer's original version of this code.
However, it's really useful to take the time to understand what all your changes did, and why they fixed your problem. Maybe you did this already - that's just not the impression I got from the phrase
What I figured out would work after some googling
when you get a compile error or warning, read it and try to understand it.
if you don't understand the error - and this is normal, certainly while you're learning - then hacking on the code until it works is perfectly fine. At least sometimes it's quicker, and the knowledge that you made progress is its own reward.
if hacking away at the code with the internet at your disposal doesn't get a solution, you'll just have to study the error message more. Turning all compiler errors and warnings on, and trying multiple compilers can both help - even if they all fail, the messages might be more useful. (I often find clang has useful errors, and godbolt.org is super helpful).
if hacking away at the code does get a solution, you should still try and understand why. Now you can see what you changed, look at the original error and try to understand why your changes fixed it. If you made multiple changes, were they all really necessary? Do you understand what they all did, and why?
If you do this, you can fix the next related problem faster, rather than going through the whole trial-and-error process again. You can even write better code that avoids the problem in the first place.
This is the part that actually constitutes learning, which is why I'm making a point of addressing it.
The important fix was changing the lines
include <iostream>
main()
to
#include <iostream>
int main()
because the former aren't legal C++. If your lecturer really wrote exactly that and you didn't somehow mis-copy, then I have no idea why their example worked.
The Visual Studio-specific stuff is the precompiled header, as described in Gabriel's answer.
But the remaining change is essentially cosmetic. Replacing:
using namespace std;
with
using std::cout;
Doesn't affect anything in your code, and just using
std::cout << "Hello world! :-)";
(with no using at all) would work just as well.

Related

Can I tell GCC to fail if I include header files unnecessarily?

The project I'm working on recently made a big effort to cleanup the code by turning on all the strictest GCC warnings and iterating until it compiled. Now, for instance, compilation fails if I declare a variable and don't use it.
After my latest development task there I see that there is a header file included somewhere that is now unnecessary. Is there any good way to find other such header files (and in such a way reduce dependencies) other than trying to remove a header file and seeing if anything breaks?
I am using GCC 4.3.2 on Linux.
No, there's no way to get gcc to fail if a header isn't required. Included headers can contain pretty much anything, so it is assumed that whoever included them had good reason to do so. Imagine the following somewhat pathological case:
int some_function(int x) {
#include "function_body.h"
return x;
}
It's certainly not good form, but it would still compile if you removed the include. So, an automatic checker might declare it "unnecessary," even though the behavior is presumably different when the function body is actually there.

Where is the source code for isnan?

Because of the layers of standards, the include files for c++ are a rats nest. I was trying to figure out what __isnan actually calls, and couldn't find anywhere with an actual definition.
So I just compiled with -S to see the assembly, and if I write:
#include <ieee754.h>
void f(double x) {
if (__isinf(x) ...
if (__isnan(x)) ...
}
Both of these routines are called. I would like to see the actual definition, and possibly refactor things like this to be inline, since it should be just a bit comparison, albeit one that is hard to achieve when the value is in a floating point register.
Anyway, whether or not it's a good idea, the question stands: WHERE is the source code for __isnan(x)?
Glibc has versions of the code in the sysdeps folder for each of the systems it supports. The one you’re looking for is in sysdeps/ieee754/dbl-64/s_isnan.c. I found this with git grep __isnan.
(While C++ headers include code for templates, functions from the C library will not, and you have to look inside glibc or whichever.)
Here, for the master head of glibc, for instance.

Visual studio 2005: is there a compiler option to initialize all stack-based variables to zero?

This question HAS had to be asked before, so it kills me to ask it again, but I can't find it for all of my google and searching stackoverflow.
I'm porting a bunch of linux code to windows, and a good chunk of it makes the assumption that everything is automatically initialized to zero or null.
int whatever;
char* something;
...and then immediately doing something that may leave 'something' null, and testing against 'something'
if(something == NULL)
{
.......
}
I would REALLY like not to have to go back throughout this code and say:
int whatever = 0;
char* something = NULL;
Even though that is the proper way to deal with it. It's just very time consuming.
Otherwise, I declare a variable, and it's initialized to something crazy if I don't set it myself.
This option doesn't exist in MSVC, and honestly, whoever coded your application made a big mistake. That code is not portable, as C/C++ say that uninitialized variables have an undefined value. I suggest setting the "treat warnings as errors" option and recompiling; MSVC should give you a warning every time a variable is used without being initialized.
No - there's no option to do that in MSVC.
Debug builds will initialize them with something else (0xcc I think), but not zero. Unfortunately, your code is bugged and needs fixed (of course this applies only to automatic variables -for statics and globals it's fine to assume they're zero initialized). I'm surprised there was any compiler that supported that behavior - if there's an option to do that in GCC, I haven't heard of it (but I'm no expert in the dusty corners of GCC).
You may hear that an earlier version of MSVC would init variables to zero in debug builds (similar to the way 0xcc is used in VS 2005), but as far as I know that's untrue.
edit ----------
Well, I'll be damned - GCC does (or did?) have the -finit-local-zero option. Looks like it's there mostly for Fortran support, I think.
I'd suggest using compiler warnings about using uninitialized variables to help you catch 99% of your problems. I know it's not a great bit of work, but it should be done if at all possible.
Interestingly, MSVC now does have the ability to do this. The Microsoft Security team wrote a blog post about it here, and there's a CppCon talk here.
Unfortunately, it doesn't seem like this option is exposed to the public. This page lists a bunch of 'hidden MSVC flags', and it includes an option called -initall, so that might be it.
What I ended-up doing was switching to /w4. At this level, it caught most of the "yeah, that's going to be an issue" areas of initialization. Otherwise, there's nothing that can change everything from being 0xcccccccc on initialization to 0x00000000 that I saw.
Massive thanks to everyone for answering this, and yes, we will tighten it up in the future.

stange -I effect with make and bad -L

I am trying to build an automated build system. It took me a little while to change a working wii generic makefile to a working win32 (using mingw32) makefile.
my make is here http://pastie.org/319482
The weird effect is, if i remove the a preceding the paths in ABS_INCL (line 31) the build doesnt work and complains about missing a header which is specified by the first path. Why is it doing this? i cant track the problem down.
The next issue is when i dropped in code that requires libcurl, i can still compile but no longer link as expected. I added curl to my libs (line 47) and the path (line 53) and it looks like i am including it right and the lib is in the right order (i tried to touch as little as possible while converting wii to win32) and i cant see the problem. Does anyone know why this is happening?
here is simple source to test with
#include <stdio.h>
void main2();
int main( int argc, const char* argv[])
{
int a=0;
printf("hey");
main2();
return 0;
}
#include <curl/curl.h>
void main2()
{
CURL *curl = curl_easy_init();
curl_easy_cleanup(curl);
}
You're not getting a lot of answers here - I'm going to go out on a limb and tell you it's because of your really badly written title. I've read it maybe 20 times as it scrolled down the home page and I still don't really get it. There is the obvious spelling mistake, and I want to go in and fix that but then there is the whole weirdness with the "-l" and "-L" and I can't tell where you are going with that.
So, most people will look at that and just blank out and move on. Assuming they get past that, you failed to add the useful information contained within your makefile to the question and so you've gotta go off and read it on the other site.
Finally, as one more hurdle, your makefile is too long to easily read and absorb. So assuming someone like me who is really kind of determined goes and reads it, it's too difficult to tell where the problem could lie within that. You need to edit it down to probably ten lines or less, and then assuming you haven't been able to figure out the problem, you could then post just those few lines that showed the problem in your question and then with a decent title and some good descriptive text, you'll probably get your answer.
I'm guessing the answer to your question isn't even that hard, you've successfully managed to obfuscate it to the point that most people wont even bother.

Xcode equivalent of ' __asm int 3 / DebugBreak() / Halt?

What's the instruction to cause a hard-break in Xcode? For example under Visual Studio I could do '_asm int 3' or 'DebugBreak()'. Under some GCC implementations it's asm("break 0") or asm("trap").
I've tried various combos under Xcode without any luck. (inline assembler works fine so it's not a syntax issue).
For reference this is for an assert macro. I don't want to use the definitions in assert.h both for portability, and because they appear to do an abort() in the version XCode provides.
John - Super, cheers. For reference the int 3 syntax is the one required for Intel Macs and iPhone.
Chris - Thanks for your comment but there are many reasons to avoid the standard assert() function for codebases ported to different platforms. If you've gone to the trouble of rolling your own assert it's usually because you have additional functionality (logging, stack unwinding, user-interaction) that you wish to retain.
Your suggestion of attempting to replace the hander via an implementation of '__assert" or similar is not going to be portable. The standard 'assert' is usually a macro and while it may map to __assert on the Mac it doesn't on other platforms.
http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeProjectManagement/090_Running_Programs/chapter_11_section_3.html
asm {trap} ; Halts a program running on PPC32 or PPC64.
__asm {int 3} ; Halts a program running on IA-32.
You can just insert a call to Debugger() — that will stop your app in the debugger (if it's being run under the debugger), or halt it with an exception if it's not.
Also, do not avoid assert() for "portability reasons" — portability is why it exists! It's part of Standard C, and you'll find it wherever you find a C compiler. What you really want to do is define a new assertion handler that does a debugger break instead of calling abort(); virtually all C compilers offer a mechanism by which you can do this.
Typically this is done by simply implementing a function or macro that follows this prototype:
void __assert(const char *expression, const char *file, int line);
It's called when an assertion expression fails. Usually it, not assert() itself, is what performs "the printf() followed by abort()" that is the default documented behavior. By customizing this function or macro, you can change its behavior.
__builtin_trap();
Since Debugger() is depreciated now this should work instead.
https://developer.apple.com/library/mac/technotes/tn2124/_index.html#//apple_ref/doc/uid/DTS10003391-CH1-SECCONTROLLEDCRASH
For posterity: I have some code for generating halts at the correct stack frame in the debugger and (optionally) pausing the app so you can attach the debugger just-in-time. Works for simulator and device (and possibly desktop, if you should ever need it). Exhaustively detailed post at http://iphone.m20.nl/wp/2010/10/xcode-iphone-debugger-halt-assertions/
I found the following in an Apple Forum:
Xcode doesn't come with any symbolic breaks built in - but they're
quick to add. Go to the breakpoints window and add:
-[NSException raise]
kill(getpid(), SIGINT);
Works in the simulator and the device.
There is also the following function that is available as cross platform straight Halt() alternative:
#include <stdlib.h>
void abort(void);
We use it in our cross platform engine for the iPhone implementation in case of fatal asserts. Cross platform across Nintendo DS/Wii/XBOX 360/iOS etc...

Resources