How to display a #defined constant during build, in Visual Studio 2010? - visual-studio-2010

I've seen this, but none of the answers worked for VS2010. The constant's (or should I call it variable?) numerical value didn't get displayed
This line of code #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX is turning out to be true when I'm actually programming in windows. I need to see the value of OGRE_PLATFORM_WIN32 and OGRE_PLATFORM_LINUX during the build process itself. Could you help with how to go about it?

You can check the preprocessor output using:
/E - preprocess to stdout or
/P - preprocess to file or
/EP - preprocess to stdout without #line directives
options in visual studio

First, check the preprocessor defines in project options - active configuration and all configurations, and make sure the right things are defined.
If you are still having problems, try substituting this for your main method:
#include <iostream>
int main()
{
#ifdef OGRE_PLATFORM_LINUX
std::cout << "OGRE_PLATFORM_LINUX = " << OGRE_PLATFORM_LINUX << "\n";
#else
std::cout << "OGRE_PLATFORM_LINUX not defined.\n";
#endif
#ifdef OGRE_PLATFORM_WIN32
std::cout << "OGRE_PLATFORM_WIN32 = " << OGRE_PLATFORM_WIN32 << "\n";
#else
std::cout << "OGRE_PLATFORM_WIN32 not defined.\n";
#endif
#ifdef OGRE_PLATFORM
std::cout << "OGRE_PLATFORM = " << OGRE_PLATFORM << "\n";
#else
std::cout << "OGRE_PLATFORM not defined.\n";
#endif
return 0;
}
Also, did you create the project, was it created by some type of pre-make (CMake, automake, etc) system, did you download it from somewhere? If you didn't create it, somebody could have ported over some Linux code without checking their preprocessor options.

Related

Preprocessor inconsistencies in Visual Studio

I'm compiling the following C++ code in Visual Studio 2015 (update 3):
#include <iostream>
using namespace std;
////////////////////////////////////////
#define UNDERSCORE1(a,b) a ## _ ## b
#define UNDERSCORE(a,b) UNDERSCORE1(a,b)
#define STRINGIFY1(x) #x
#define STRINGIFY(x) STRINGIFY1(x)
#define VALUE(x) UNDERSCORE(x, VALUE)
#define NEXT(x) (VALUE(x) + 1)
/////////////////////////////////////////
#define X1_VALUE 0
#define X2_VALUE NEXT(X1)
#define X3_VALUE NEXT(X2)
#define TOTAL NEXT(X3)
int main() {
cout << STRINGIFY(TOTAL) << endl;
cout << TOTAL << endl;
return 0;
}
The result printed to stdout is very strange:
(X3_VALUE + 1)
3
When trying the same on gcc, build fails (expectedly).
When commenting out cout << TOTAL << endl; I get something different altogether:
(NEXT(X2) + 1)
Actually gcc behavior makes sense, since NEXT macro is called recursively: NEXT(X3) is expanded to X3_VALUE which in turn expands to NEXT(X2), so the second expansion of NEXT macro (NEXT(X2)) is not performed.
What doesn't make sense is Visual Studio behavior:
When printing the macro TOTAL using STRINGIFY, NEXT seems to be expanded twice to yield X3_VALUE.
When compiling the macro TOTAL directly to send it to cout, NEXT is expanded all the way! As if the preprocessor ran multiple times to recursively expand NEXT.
Another thing I tried was to compile this code in Visual Studio with the /P compiler option, to get the preprocessed code:
int main() {
cout << "(X3_VALUE + 1)" << endl;
cout << (((0 + 1) + 1) + 1) << endl;
return 0;
}
So is it, as I suspect, a bug in Visual Studio preprocessor? Or a legit undefined behavior?
Perhaps this behavior can be abused to truly expand macros recursively? I know that a limited recursion is possible with some tricks but is limited to a predefined number of scans. In this case I did not observe a limit to the number of times NEXT is expanded.
As Hans mentioned in the comments, the MSVC preprocessor is not conformant.
You can enable the conformant preprocessor with -experimental:preprocessor.
Here is a simplified repro + solution: https://godbolt.org/z/7u_-bH

Visual studio: How to create hyperlink in comments section in c++ code to go to different lines within the code

I need to create a hyper link in my comments section of my c++ code so that , when I click on the link, it should take me to a specific line of the same code base.
That specific line could be in same file or different, but of course the same project.
Is this possible in Visual studio when writing c/c++ code.
For example,
int main()
{
Marks m1(10,20);
Marks m2(30,40);
Marks m3,m4;
//Line 7
std::cout <<m1.get_int_marks()<<std::endl;
std::cout << m1.get_ext_marks() << std::endl;
m3 = m1 + m2;
//Line 14
std::cout << m3.get_int_marks() << std::endl;
std::cout << m3.get_ext_marks() << std::endl;
m4 = m1 - m2;
int x = 10 + 20;
std::cout << m4.get_int_marks() << std::endl;
std::cout << m4.get_ext_marks() << std::endl;
std::cout << x << std::endl;
return 0;
}
In the above code , can I create a hyperlink in the comments, at line 7 to go to line 14.
Used case can be to go to any line of any file in the project.
Thanks in advance.
In case you want a link to method, you can use empty function macro to prevent compiler warnings, privates, etc.
Put pseudo code inside and follow by F12 (Visual Studio) or similar key elsewhere.
Includes are often mandatory for jump to wanted method directly.
#define CALLERS(...)
#include "myClass.h"
#include "myFunctions.h"
CALLERS(myClass::myMethod; function();)

SDL2: undefined references to strange functions

i have written this small piece of Code for testing purposes:
#include <iostream>
#include "SDL2/SDL.h"
int main(int argc, char* argv[]) {
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
printf("Unable to initialize SDL: %s\n", SDL_GetError());
return 1;
}
// Betriebssystem ermitteln
std::string PlatFormString;
PlatFormString = SDL_GetPlatform();
std::cout << PlatFormString << "\n";
// Separator ermitteln
char Separator = '/';
if (PlatFormString == "Windows") {
Separator = '\\';
}
std::cout << "Separator: " << Separator << "\n";
// Installationspfad ermitteln
std::string InstallPath;
InstallPath = SDL_GetBasePath();
std::cout << InstallPath << "\n";
// Benutzerverzeichnis ermitteln
char* UserPath;
UserPath = SDL_GetPrefPath("TFF", "Blaster");
if (UserPath == nullptr) {
std::cout << "No Userpath aviable !! \n";
}
else {
std::cout << UserPath << "\n";
}
SDL_Quit();
return 0;
};
Under Linux eerthing works fine.
But under Windows, i am getting these strange errors ...
-------------- Build: Debug in Test (compiler: GNU GCC Compiler)---------------
g++.exe -LD:\mingw64 -LD:\mingw64\bin -LD:\mingw64\include -LD:\mingw64\include\SDL2 -LD:\mingw64\lib -o bin\Debug\Test.exe obj\Debug\src\Test.o -lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer ..\..\mingw64\lib\libSDL2main.a ..\..\mingw64\lib\libSDL2.a
..\..\mingw64\lib\libSDL2.a(SDL_systimer.o): In function `timeSetPeriod':
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x64/../src/timer/windows/SDL_systimer.c:58: undefined reference to `__imp_timeBeginPeriod'
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x64/../src/timer/windows/SDL_systimer.c:52: undefined reference to `__imp_timeEndPeriod'
/Users/slouken/release/SDL/SDL2-2.0.3-source/foo-x64/../src/timer/windows/SDL_systimer.c:58: undefined reference to `__imp_timeBeginPeriod'
and so on. I dont know whats going on there. Can anyone help ?
I#m using Codeblocks 13.12, minGW64 (4.8.1), SDL 2.0.3 and Windows 7 64bit
You need to link against winmm.lib.
Try adding
#pragma comment(lib, "winmm.lib")
to your source.
I am posting this about a year later but for the future searchers here is the solution. Replace libSDL2.a with libSDL2.dll.a and it will compile just fine. The issue has something to do with dynamic and static linking with a windows machine or something I personally do I understand it completely but it works.
I came across the solution by reading this article: http://tech.yipp.ca/sdl/how-to-fix-libsdla-undefined-reference/
However this goes on a whole other solution I read between the lines or more particularly.
This is a really a rare problem that would occur only when you try to link with libSDL.a static library instead of the dynamic library SDL.dll. Then you have to add those library that SDL.dll normally links against which are the three above.

UpdateDriverForPlugAndPlayDevices error is telling me I'm *not* doing something that I am

I'm working on a means of installing a driver. Because of the multiple platforms on which this must work, I'm shelling-out to both devcon and dpinst to do the work of driver install/update/removal when needed. While testing, I'm having problems with the shelling out to devcon. To isolate, I wrote a small app to do what devcon does in update see here, using the devcon source from the WinDDK for reference. I'm having some problems with UpdateDriverForPlugAndPlayDevices() from Setup API (actually part of Newdev.dll) see here. The source code is here:
#include <iostream>
#include <Windows.h>
#include <newdev.h>
int main(int argc, char** argv) {
// Go through the same steps as does dev con for this update crap
char infFile[MAX_PATH];
if(3 > argc) {
std::cerr << "an INF and HW ID must be specified" << std::endl;
return 1;
}
DWORD result(GetFullPathName(argv[1], MAX_PATH, infFile, NULL));
if((result >= MAX_PATH) || (0 == result)) {
std::cerr << "path is too long for buffer" << std::endl;
return 1;
}
if(GetFileAttributes(infFile) == -1) {
std::cerr << "file doesn't exist" << std::endl;
return 1;
}
BOOL reboot(FALSE);
if(!UpdateDriverForPlugAndPlayDevices(NULL, argv[2], infFile, INSTALLFLAG_FORCE, &reboot)) {
std::cerr << "Failed to install the driver. Code: "
<< GetLastError()
<< std::endl;
return 2;
}
if(reboot) {
std::cout << "A reboot is needed to complete driver install"
<< std::endl;
}
return 0;
}
The program fails when UpdateDriverForPlugAndPlayDevices() returns false. This then prints the error code, returned by GetLastError(), so I'd know what went wrong. The error code returned: 259. According to this resource says this is ERROR_NO_MORE_ITEMS. According to the link for UpdateDriverForPlugAndPlayDevices(), this function returns this error code when, "The function found a match for the HardwareId value, but the specified driver was not a better match than the current driver and the caller did not specify the INSTALLFLAG_FORCE flag." You'll notice from my code that I did specify this flag.
I do not know where to go from here. Can someone please identify from this code what it is I'm missing? This just has the "feel" of something simple, but I'm totally missing it.
Thank you,
Andy
The problem appeared to be not with the code but with the INF file. Interesting that the documentation for the function said that using that flag will force the install but didn't when the INF file didn't "list" any device classes in the models section. This is how I was able to install eventually. I added the correct device class to the models section in the INF.
EDIT Sep. 17, 2020
It was requested by someone just today (of the edit) to add an example from the INF. It's been 8 years since I had this issue and I no longer work for this team. However, as best as I can recall, and drawing heavily upon the docs for INF Models Section and INF Manufacturers Section, I hope this helps.
Essentially, the class is specified by the Models Section and the model is specified by the Manufacturer Section.
[Manufacturer]
%MfgName%=Standard,NTamd64
[Standard.NTamd64]
%DeviceString%=<class path or GUID>\<device>
[Strings]
MfgName=ACME
DeviceString="Device Type"

In Boost.Test, how to obtain the name of current test?

In Boost.Test, how can I obtain the name of the current auto test case?
Example:
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(MyTest)
{
std::cerr << "Starting " << test_name << std::endl;
// lots of code here
std::cerr << "Ending " << test_name << std::endl;
}
In the example, I want the variable test_name to contain "MyTest".
There is an undocumented* function that may be called for that purpose. The following line will flush the name of the current test to cerr:
#include <boost/test/framework.hpp>
...
std::cerr << boost::unit_test::framework::current_test_case().p_name
<< std::endl;
Note however that using this API does not flush the parameters in case of parametrized tests.
You might also be interested in the test checkpoints** (which seems to be what you want to do.)
#include <boost/test/included/unit_test.hpp>
...
BOOST_AUTO_TEST_CASE(MyTest)
{
BOOST_TEST_CHECKPOINT("Starting");
// lots of code here
BOOST_TEST_CHECKPOINT("Ending");
}
EDIT
* The current_test_case() function is now documented, see the official Boost documentation.
** BOOST_TEST_CHECKPOINT was previously called BOOST_CHECKPOINT. See the Boost changelog (1.35.0).
A different question about suite names gives a way to extract the name rather than just printing it:
auto test_name = std::string(boost::unit_test::framework::current_test_case().p_name)

Resources