I have three files as below
Test.cpp
void helloworld()
{
disable pf;
pf.Disable();
printf("No statement \n");
}
int main()
{
disable dis;
helloworld();
printf("Hello World");
system("pause");
return 0;
}
disable.cpp
#include "StdAfx.h"
#include "disable.h"
disable::disable(void)
{#define printf(fmt, ...) (0)}
disable::~disable(void)
{}
void disable::Disable()
{
#define printf(fmt, ...) (0)
}
disable.h
#pragma once
class disable
{
public:
disable(void);
~disable(void);
void Disable();
};
After executing, I am getting output as No Statement Hello World.
But I would like to disable these two printf statements by calling Disable function and disable constructor..
Please help me why it is not working and how to solve this. Please help.
But things works fine if I do like
main()
{
#define printf(fmt, ...) (0)
printf("Hello World");
}
But why not if I am calling it from a function?
You can disable the printf ouput by:
close(STDOUT_FILENO);
or you can use also:
fclose(stdout);
This will disable all output to the stdout
Example:
#include<stdio.h>
#include<stdlib.h>
int main(){
printf ("This message will be displayed\n");
fclose(stdout);
printf ("This message will not be displayed\n");
// to reopen the stdout, this is another question
return 0;
}
Note
If you are using sockets in your program, than you have to be careful here because the close of stout will cause the redirection of the output to the sockets
A macro doesnt obey scope rules, c++ syntax rules, or anything. It is a text replacement engine, only.
When you say #define printf(fmt, ...) (0) in disable.cpp, it is defined ONLY in disable.cpp. If you were to write that in disable.h, it would be defined in all files that include from disable.h.
The only way to control a macro is with a macro (#if and #ifdef and their ilk). So what you want to to can be achieved by the following.
#define DISABLE_PRINTF
#ifdef DISABLE_PRINTF
#define printf(fmt, ...) (0)
#endif
But this will be a global disable and can only be undone by commenting out the first #define and recompiling the code. There is no way to do selective/scope based control of disabling using macros.
Edit: Instead of redefining printf itself, it is recommended to write a wrapper which is defined in terms of printf for this purpose.
On implementations that support it, you could redirect the stdout buffer to "disable" the console, and restore it when you want to "enable" it again. Here's a code sample which works (at least) on Linux with gcc.
NOTE This is a implementation-specific solution and uses dup() and dup2() from unistd.h. It is not guaranteed by the standard to work everywhere.
#include <cstdio>
#include <unistd.h>
int main() {
printf("Hello world.\n");
fpos_t pos;
fgetpos(stdout, &pos); // save the position in the file stream
int fd = dup(fileno(stdout)); // use the dup() function to create a copy of stdout
freopen("dummy.txt", "w", stdout); // redirect stdout
printf("Hello nobody.\n"); // this is not printed to the "usual" stdout
fflush(stdout);
dup2(fd, fileno(stdout)); // restore the stdout
close(fd);
clearerr(stdout);
fsetpos(stdout, &pos); // move to the correct position
printf("Hello world again.\n"); // this is printed back to the "usual" stdout
}
You could put that logic into enable() and disable() functions.
Let me emphasise, this is an implementation-specific solution. I am not aware of any standard-conforming solution to restore the standard streams after they have been redirected.
Related
Say I have a function like
void printToSomewhere(FILE* stream, char* msg){
fprintf(stream, "%s", msg);
}
If I want the stream to be stdout, do I have to declare that before in the calling function:
...
FILE* stdout;
printToSomewhere(stdout, "printing to stdout");
...
or can I call the function without having to define/include/etc stdout explicitly?
...
printToSomewhere(stdout, "printing to stdout");
...
As with every variable, you have to declare stdout before using it. The variable stdout is declared in the header file stdio.h (or cstdio in C++). By including stdio.h (or cstdio), stdout becomes visible.
On many platforms, you can also simply declare stdout as an extern variable:
extern FILE *stdout;
although doing so is discouraged, as the C standard requires stdout to be a macro and allows it to expand to something that is not even a variable. On most plaforms however, stdio.h defines this macro simply as
#define stdout stdout
but you should refrain from making this assumption in portable software.
Yes. STDOUT is always file descriptor 1 (mandated by POSIX).
This will work:
#include <stdio.h>
#include <stdlib.h>
void printToSomewhere(FILE* stream, const char* msg){
fprintf(stream, "%s", msg);
}
int main()
{
FILE* f = fdopen(1, "w+");
printToSomewhere(f, "Hello\n");
fclose(f);
return 0;
}
expected output:
Hello
My application uses another output than the standard output for logging information, which is why I wrote my own Log(), Error(), Panic() and Assert() functions. To organize things nicely, I enclose all the debugging stuff in a Debug namespace.
It would make more sense for the Assert() function to also provide a source file and line number, which is only possible using the __LINE__ and __FILE__ macros. However, it is pretty unpleasant, inefficient etc... to always have to specify these two parameters.
So this is how my code would look like:
namespace Debug {
void Assert (int condition, std::string message, std::string file, int line);
}
My question is, is it possible to place a macro which includes those two parameters inside the Debug namespace? Like this:
namespace Debug {
void Assert_ (int condition, std::string message, std::string file, int line);
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
// Output: Assertion failed on line 10 in file test.cpp:
// Some_condition should be true
Is this valid c++? If not, is there any way of making this work?
#define is a preprocessor directive. The macros are being replaced before anything else apart from removing comments (which means, before compilation). So at the time macros are replaced, the compiler knows nothing about your namespaces.
As other people state, in your case it will be fine. However, This is how you can get problems:
namespace A
{
void Assert_ (int condition, std::string message, std::string file, int line)
{
std::cout << "A";
}
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
namespace B
{
void Assert_ (int condition)
{
std::cout << "B";
}
#define Assert(a,b) Assert_(a)
}
int main(int argc, char *argv[])
{
A::Assert(0,"asdasd");
B::Assert(0,"asdasd");
}
So while it looks like the defines are "in the namespaces", they are not, and the last #define will be always be used, which in this case will lead to a compile-time error, because the code in main will be replaced by:
A::Assert(0);
B::Assert(0);
instead of
A::Assert(0,"asdasd", _FILE_, _LINE_);
B::Assert(0);
No, the preprocessor doesn't care about namespaces at all. In fact, the preprocessor runs, at least conceptually, before the compiler sees anything.
For myself, I just do a standard ASSERT macro, and expect that no "sane namespace" has something called ASSERT. Problem solved. Should I require a library that has an ASSERT of its own then I can still decide how to deal with this; however, the only library that I'm currently using with its own "assert" calls it BOOST_ASSERT or something like that...
namespace Debug
{
void Assert_(int condition, std::string message, std::string file, int line);
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
}
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
This specific usage would do exactly what you want, but the Assert macro is in no way part of the Debug namespace... it's exactly as if you'd done:
namespace Debug
{
void Assert_(int condition, std::string message, std::string file, int line);
}
#define Assert(a,b) Assert_(a, b, __FILE__, __LINE__)
// .... Somewhere where I call the function ....
Debug::Assert (some_condition, "Some_condition should be true");
Here, the substitution works not because Assert was in the Debug namespace (it's not in your code or this code, and the preprocessor has no clue what namespaces are about) - it works because Assert is recognised as an identifier for a macro, the substitution of Assert_ is made, then later the compiler proper happens to find there's a Debug::Assert_
So, say you have somewhere later in your translation unit you have some completely unrelated code:
my_object.Assert(my_functor);
The macro substituion will still kick in to produce a compile-time error saying you have the wrong number of arguments to a macro. Say the unrelated code was instead:
my_object.Assert(my_functor, "some text");
Then that would be replaced with:
my_object.Assert_(my_functor, "some text", __FILE__, __LINE__);
(Separately, it's standard practice not to use lower case letters in preprocessor macro names).
You can try __PRETTY_FUNCTION __ macro to print all the namespaces including function arguments.
Yes, and your macro would expand to exactly what you expect.
Debug::Assert (some_condition, "Some_condition should be true");
would be replaced by
Debug::Assert_(some_condition, "Some_condition should be true", __FILE__, __LINE__)
So I have looked here and here and at a few other links mentioned in the first question and I have the following code already:
The .cpp file:
#include "arp_piping.h"
#include <string>
#include <iostream>
#include <stdio.h>
std::string exec(char* cmd, FILE* pipe) {
pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
std::string result = "";
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return result;
}
The header/linker file:
#ifndef ARP_PIPING_H
#define ARP_PIPING_H
#endif
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
my function goes here something like
EXTERNC .....exec(char* cmd, FILE* pipe) ????
#undef EXTERNC
My question is what goes in the bit above as I am unsure what to be typing. I am trying to call the function in the .cpp file from my C main function int main(int argc, char** argv) {}
To call C++ functions from C you need to do two things. 1) Let the C++ code know it's going to be used by C so that it can generate C-friendly symbols. 2) Hide any functionality that C can't understand.
The first part is easily achieved by simply defining the functions as you would in C (I.E. don't use any C++ only features like namespaces) and then wrapping them in an extern "C" block if C++ is defined. You basically want your header file to contain C-only code, and then just open the extern block at the top, and close it at the bottom of the file (my example will make this more clear).
The second part is a little trickier, but not too difficult. In your case, your function returns a std::string which is a C++ only class. It can not be used in C and therefore either needs to be replaced with something that can be used in C, or it needs to be hidden behind something that C can use. For the sake of argument let's assume you can't replace std::string with say, char*. In this case you need to hide std::string from the C-facing code. The common way of doing this is to use an opaque pointer.
Basically, the C-facing code deals only with a pointer to something. That something it neither knows about, nor cares about. The C++ code is free to use a std::string internally, but must make sure to hide it before interfacing with the C API. In my example, you can see I've provided an opaque pointer to a struct I've called cppstring.
In the source file, cppstring is just a struct that holds a std::string. I've changed your example code to use the new cppstring struct. One important thing to note is that because the C code can only deal with a pointer to a cppstring, we need to create it on the heap in our C++ code and return the pointer to it. This means that we must provide the C users some way of freeing it when they're done, which I've also provided in the example.
Using this technique you can wrap the entirety of std::string behind a C API, allowing C users to use all of the functionality that std::string provides. I've provided an example of wrapping std::string::substr to show you how.
N.B. I haven't compiled nor tested this code and for the sake of simplicity I haven't included any of the relevant header files, etc. Nevertheless, it should be enough to get you started.
// C header
#ifdef __cplusplus
extern "C" {
#endif
typedef struct cppstring *cppstring_p;
cppstring_p exec(char *cmd, FILE *pipe);
void free_cppstring(cppstring_p cppstr);
/* example of wrapping std::string::substr for C users */
cppstring_p substr(cppstring_p str, int pos, int count);
#ifdef __cplusplus
}
#endif
// CPP source
struct cppstring {
std::string data;
cppstring(void) {}
cppstring(std::string const& s) : data(s) {}
};
cppstring_p exec(char *cmd, FILE *pipe) {
pipe = _popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[128];
auto result = new cppstring;
while(!feof(pipe)) {
if(fgets(buffer, 128, pipe) != NULL)
result->data += buffer;
}
_pclose(pipe);
return result;
}
void free_cppstring(cppstring_p cppstr) {
delete cppstr;
cppstr = nullptr;
}
cppstring_p substr(cppstring_p str, int pos, int count) {
assert(str);
return new cppstring(str->data.substr(pos, count));
}
You need to declare the function as extern "C" in the cpp file:
extern "C" char *exec(char* cmd, FILE* pipe) {
...
}
In the header/linker file you need to declare it's prototype with the keyword "extern", like so:
extern char *exec(char* cmd, FILE* pipe);
Also, are you sure you want to return a c++'s std::string to your C code?
I need to create some API, with which, by calling a function, the correct one for the current operating system will be called.
So I went with that :
main.cpp :
#include "api.h"
int main() {
helloWorld();
return 0;
}
api.h :
void helloWorld();
api.cpp :
void helloWorld() {
#ifdef __gnu_linux__
printf("Hello World of Linux");
#endif
#ifdef WIN32
printf("Hello World of Windows");
#endif
}
But this doesn't satisfy me. When I'll have big functions, such as the one to get all childs of a process under Linux, and many others, I'll have a problem of space, of visibility to maintain the code.
I tryed to include different headers depending on the underlying OS, but this doesn't work very well, I can't have two headers (one for Windows, one for Linux) and only one C++ file.
So, do you know how I could separate the code for Linux and Windows so I end up with two file (one only for Linux and one only for Windows) with one header file that will have a #ifdef condition ? I couldn't make it work ...
I did it the following way:
main.cpp and api.h does not suffer any modification.
api.cpp:
#ifdef linux
#include "linux_api.h"
#endif
#ifdef WIN32
#include "windows_api.h"
#endif
void helloWorld() {
#ifdef linux
helloWorld_linux();
#endif
#ifdef WIN32
helloWorld_win32();
#endif
}
Then you need to provide linux_api.h, linux_api.cpp and windows_api.h, windows_api.cpp. The advantage is that this four files are already platform specific. You only have to create the "glue code" in api.cpp for each function.
linux_api.h:
void helloWorld_linux();
linux_api.cpp:
#include "linux_api.h"
#include <cstdio>
void helloWorld_linux()
{
std::printf( "Hello world from linux..." );
}
Hope this helps.
I have a logging function which accepts variadic parameters. This works fine for say android logging and printf, but I want to do the same with std::cout and file streams. Is there an easy way solve this?
void LogManagerImpl::LogInfo(const char* msg, ...)
{
va_list argptr;
va_start(argptr, msg);
/* Log to stdout */
if (mLogToStdOut)
{
#ifdef ANDROID
__android_log_vprint(ANDROID_LOG_INFO, __ENGINE_LOG_TAG, msg, argptr);
#elif defined _WIN32 || _WIN64
//printf ("%s:%s",__ENGINE_LOG_TAG,"INFO:"); vprintf(msg, argptr); printf("\n");
// how do I do the same as above except with for example std::cout?
#endif
}
/* Log to file */
if (mLogToFile)
{
// TODO
}
va_end(argptr);
}
Don't try to use a variadic wrapper for C++ streams, just use the corresponding C API such as vprintf/vnsprintf. Wrapping streams in this way just throws away all the benefits and causes additional complexity.
Why not have your wrapper API use streams, and map them to printf on Android platforms. That way you get all the benefits of streams and only lose them on platforms that don't natively support them.