How do I use if statement outside a function in C++ - c++

I want to check the value of a variable that I set inside the main function, but the if statement is not inside a function.
Here is what I have so far.
bool condition;
#if(condition)
:
:
:
some code
#endif
int main(int argc, char *argv[])
{
condition = processArgs(argc, argv);
}
From my understanding macros are executed during compilation time and not run time. Is there another way to check the value of the variable condition outside functions. The value of the variable condition is set depending on the command line arguments passed by the user.
So how do I use if statements outside the scope of functions? Because macro if does not work.

If you are doing those tasks using macros(I guessed from the question) then you can try doing:
#define _condition(x) Condition(x)
bool Condition(bool result)
{
if(!result)
{
///some code
}
return false;
}
int main(int argc, char *argv[])
{
bool result=processArgs(argc, argv);
_condition(result);
}
This way you'll be defining a macro for checking the value of the result variable that I added. The macro _condition will call the function for you and you can add any more code in the function without making a mess of the macro because one cant possibly put a function like defining a macro. If you were not doing macros then you can try calling the function directly and not using macros. Macros are a very useful yet complicated stuff so it is hard to make such large functions that you did in the function

You want to add a function:
void myFunction(bool condition)
{
if (condition)
{
// some code
}
// some code
}
int main(int argc, char *argv[])
{
bool condition = processArgs(argc, argv);
myFunction(condition);
}
that way, you tell the compiler when to run it, and what condition to use.

Related

Detect specific tag match in Catch2 at runtime

I have integration tests in my Catch2 project that depend on some expensive global state being set up. I'd like to only initialize that global state when the test runner will actually be testing the systems that depend on it.
What I have appears to work, but it's a little horrifying... it depends on rather a lot of implementation details in the Catch config.
Here's my main:
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
...
int main(int argc, const char* argv[])
{
// Construct a fake TestCaseInfo to match against the [integration] tag
const char * expensive_tag = "integration";
Catch::SourceLineInfo fake_source_line("?", 0)
Catch::TestCaseInfo fake_test_case("?", "?", "?", {expensive_tag}, fake_source_line);
Catch::Session session;
session.applyCommandLine(argc, argv);
auto test_spec = session.config().testSpec();
const bool want_integration_tests = test_spec.matches(fake_test_spec);
if(want_integration_tests)
{
do_expensive_setup();
}
return session.run();
}
And then my test file is just:
#include "catch.hpp"
...
TEST_CASE("expensive-to-initialize system", "[.integration]")
{
REQUIRE(expensive_setup_is_done());
SECTION("has property 1") { ... }
SECTION("has property 2") { ... }
...
}
Note that because there are multiple sections (and, in my actual project, multiple test cases) that depend on the global setup, I can't just move the initialization into the top of the TEST_CASE.
Is there a better way?
Just do the initialization on demand, using something like std::call_once:
TEST_CASE("expensive-to-initialize system", "[.integration]")
{
static std::once_flag init_flag;
std::call_once(init_flag, do_expensive_setup);
// ...
}
This will ensure that do_expensive_setup is called one time, but only if needed. If there are multiple places that need this setup, just wrap this in a function.
Note that if do_expensive_setup throws, it will may be called a second time. But once the function successfully exits, that's it.

Using gtest specific parameters inside the testcase

Im using gtest as the test framework for my project and I need to use the following parameter value which is passed as a gtest parameter, inside the test case
./gtest_bin --gtest_repeat=5
Currently what I'm doing is, I've created a custom Listener extended from "EmptyTestEventListener" and pass the iteration value to a global variable when the callback to the following function is received as following,
customListener class
class customListener : public testing::EmptyTestEventListener
{
customListener(int *iteration) : m_iteration(iteration) {}
virtual void OnTestIterationStart(const testing::UnitTest& unit_test, int iteration)
{
*m_iteration = iteration;
}
}
main
int g_iteration;
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
if(argc > 1)
g_array_length = atoi(argv[1]);
testing::TestEventListeners& listners = testing::UnitTest::GetInstance()->listeners();
listners.Append(new printers::customListener(&g_iteration));
return RUN_ALL_TESTS();
}
Is there an easier way to get this gtest parameter value?
If generalized, Is there a way to get any gtest specific parameter value that can used inside a testcase?
IMPORTANT NOTE
Please use with great care - as this is not documented feature and
might be changed (i.e. it might stop working) in next gtest/gmock
versions.
You can access any flag by ::testing::GTEST_FLAG(flag_name) - in your case - ::testing::GTEST_FLAG(repeat).
I got this information indirectly from this manual and by examining gtest.h file.

Google benchmark custom main

I would like to have a custom main function called before the benchmark starts to run with Google's benchmark library. So that I could setup several things. I've searched for quite a bit but I wasn't able to find anything. Should I simply modify the macro manually? Or simply use my main function and initialize the benchmark myself. Would that affect the library initialization in any way? Is there another way without requiring me to modify that macro or copying it's contents?
benchmark\benchmark_api.h
// Helper macro to create a main routine in a test that runs the benchmarks
#define BENCHMARK_MAIN() \
int main(int argc, char** argv) { \
::benchmark::Initialize(&argc, argv); \
::benchmark::RunSpecifiedBenchmarks(); \
}
BENCHMARK_MAIN() is just a helper macro, so you should be able to define your own version of main() like this:
int main(int argc, char** argv)
{
your_custom_init();
::benchmark::Initialize(&argc, argv);
::benchmark::RunSpecifiedBenchmarks();
}
Edit: you can also define global object and perform your custom initialization within its constructor. I usually do it this way, e.g. to initialize global array with input data:
int data[10];
class MyInit
{
public:
MyInit()
{
for (int n = 0; n < 10; ++n)
data[n] = n;
}
};
MyInit my_init;

C++ Exception Handling - Concrete Example

I've this program (parts of program not posted):
//Includes and functions
int main(int argc, char *argv[])
{
ifstream loc("achievements.loc", ios::binary);
getline(loc, header, static_cast<char>(1));
loc.seekg(15, ios::cur);
loc.read(reinterpret_cast<char*>(&subdirs), sizeof(subdirs));
for( int i = 0; i < nstrings; i++ )
{
loc.read(reinterpret_cast<char*>(&strid), sizeof(strid));
loc.read(reinterpret_cast<char*>(&stroffset), sizeof(stroffset));
curoffset = loc.tellg();
loc.seekg(strcodesbeg+16+stroffset);
getline(loc, codestring, '\0');
loc.seekg(curoffset);
}
}
I want to terminate the program if:
- The file is not opened;
- The header string, obtained by getline isn't equal to "String";
- Any of the read function fails;
- Any of the seekg fails;
- The strid, doesn't match with 1234.
How can I do this using C++ Exceptions? Should I use a single try{}catch(...){} block, creating functions that, for example, reads the data and sends EOF_REACHED on failure, or a try{}catch(var e){}catch(var2 e){}, a class, or any other way?
I understand the concept of the exceptions in simple function, but it gets complicated when there's a bigger program.
I didn't found too any c++ source code that uses try catch block explicitly in the main function, but works with exceptions. How this is possible?
The most verbose way to do this is to subclass a particular exception that will give you some context about what happened, for instance:
class FileNotOpenedException : public std::runtime_error {};
int main(int argc, char *argv[])
{
try
{
ifstream loc("achievements.loc", ios::binary);
if(!loc.is_open())
throw FileNotOpenedException;
// ...
}
catch(const FileNotOpenedException& e)
{
// ...
}
}
Note, however that using exceptions for expected error conditions is not necessarily good practice. Exceptions should be used only for truly "exceptional" conditions, that is something that is completely unexpected in your program, that you have no way of recovering from in the particular scope. The file not being opened above is a bad example. One of the read() or seekg() functions failing however may be more appropriate.
That said, it is possible to do what you are asking, and above is an example of one way to do it.

Creating a program in C++ that takes arguements from the command line

I am trying to learn how to make a program in C++ that when you run it, you can tell it to run and specify options all in one line. For example you can do ipconfig /all in CMD and it runs ipconfig.exe with the option /all. Another example would be shutdown -f which tells the computer to shutdown with the option -f. For example, I want to make a program that downloads something from a URL and call it for example downloader. From command line one would type downloader http://filehere.com /h which would download the file with the /h option which I would define its property in my program. I don't want code or guides on how to make a downloader I am just trying to learn how to specify options like the /h. Are there any guides out there that you know of and could post or any sample code? I have tried searching for guides, but I think I just don't know what this operation is actually called. Thank you.
You typically define your main function to take two arguments: int argc and char *argv[], such as:
int
main(int argc, char *argv[])
{
...
The first argument is how many parameters your program received, argv is a pointer to them. Note, this isn't mandated, you can name them whatever you want, but that's the convention. Just make sure your types match up.
You can use an option-parsing library, but those are often OS-specific. One simple way to check if you received a /h is:
int got_h = 0;
for (int i=0; i<argc; ++i)
if (strcmp(argv[i], "/h") == 0)
got_h = 1;
...
if (got_h)
...
argv[argc] will always be NULL to make iterating through them easier.
Some more information here: http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html
The main function takes two arguments, traditionally named argc and argv:
int main (int argc, char * argv[])
{
// ...
}
argc contains the number of arguments passed on the command line, and the argv array contains such arguments (with argv[0] being the name used to invoke your program); the last element of the argv array (i.e. argv[argc]) contains a NULL pointer.
Depending upon your proficiency and inclination to use pointers, you may prefer to capture the command line as a vector<string>:
// UNTESTED CODE
int main(int argc, char **argv) {
std::vector<std::string> args(argv+1, argv+argc);
if(args.empty()) {
std::cout << "Usage: downloader URL [options]\n";
return 1;
}
if(std::find(args.begin(), args.end(), "/h") != args.end()) {
option_h = true;
}
Download(args[0]);
}