How to printf() a user class? - c++

The program fails while compiling the code. Compiler points to printf("Version = '%s'\n", gABXVER). I guess that I actually can't write gABXVER = "V1R1", but I don't have any other idea.
class CISPFVar_BINSTR : public CISPFVar
{
protected:
char* m_pBuffer;
long m_bDefined;
public:
...
void Initialize(char* szName, long lSize, int bDefineVar = 1)
{
Uninitialize();
ZStrToCharArray(szName, m_cName, 8);
m_Size = lSize+1;
m_pBuffer = (char*)malloc(m_Size);
m_pBuffer[0] = 0;
if (bDefineVar)
ISPLINK(__VDEFINE, m_cName, m_pBuffer, __BINSTR, &m_Size);
m_bDefined = bDefineVar;
}
...
};
CISPFVar_BINSTR gABXVER;
char szLoadLibraryPath[50];
int main(
int argc,
char* argv[])
{
if (argc > 1)
if (argv[1]) strcpy(szLoadLibraryPath, argv[1]);
gABXVER.Initialize("ABXVER",4);
gABXVER = "V1R1";
printf("Version = '%s'\n", gABXVER);
return 0;
};

When you use %s in printf family of functions, the corresponding argument type needs to be const char* or something that can be converted to const char*. The argument you are using is not such a type. Perhaps you meant to use:
printf("Version = '%s'\n", gABXVER.m_pBuffer);

The compiler should compile just fine (with possible warnings for printf) because printf doesn't care what you pass to it (beyond the first parameter) or whether it matches the format string. Modern compilers or error checking progs like lint will issue a warning if the params obviously don't match, and if you have a setting "treat warnings as errors", the prog may fail to compile.
That said, CISPFVar_BINSTR needs a public copy constructor if you want to pass it as a parameter by value to a function (because at least semantically a copy will be made). Does it have one? As others remarked it's customary to help your helpers by providing any information you have. Here we are badly missing the compiler errors. (You can edit your post at any time.)
I could imagine that the class has a conversion to char* or std::string, so it may suffice to try either printf("Version = '%s'\n", (char *)gABXVER) or printf("Version = '%s'\n", (std::string(gABXVER)).c_str() ).

You can only printf things that have format specifiers designed specifically for them. There is no format specifier that accepts a value of class type, so you cannot printf one directly.
The best thing you can do is explicitly convert your object to a const char* and pass the result to printf.

In c++ you can use many techniques to implement things like streaming operators
#include <iostream>
class Whatever
{
int value = 42;
public:
int Get() const {
return value;
}
friend std::ostream& operator<<(std::ostream&, Whatever const&);
};
std::ostream& operator<<(std::ostream& os, Whatever const& what) {
os << what.Get();
return os;
}
int main() {
Whatever x;
std::cout << x << std::endl;
}
printf is unsafe
In effect, you're doing serialization of your object into a readable string.

Related

using a class type in printf()

I am experimenting to change some of the current code in a library that returns an enum for status code to a class type that has status and sub-status as shown below in status class below. One of the requirements is to have this work with lot of existing code that uses the type in == and != kind of checks all over the code base. Another requirement is to be able to use it existing printf statements all over the place.
I converted the enum to #define as below and then used operator overloading for == (will have to implement inequality later). I was expecting the printf() usage shown below to fail when I try to print status. However, surprisingly that seems to be working and printing the status_ member field value already !! How is it working ? Can someone please help make it make sense ?
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
// these are the status codes that any function can return
// for example test_function() below returns one of these
#define STATUS_OK 100
#define STATUS_ERR 200
// this is the new class that replaces the enum types
class status {
public:
status() {}
status(unsigned int status) : status_(status) {}
status(unsigned int status, unsigned int sub_status) : status_(status), sub_status_(sub_status) {}
bool operator==(const status& other) {
return (status_ == other.status_);
}
private:
unsigned int status_;
unsigned int sub_status_; // sub_status_ is meant for future usage
};
// helper function to test the main code
// this returns possible status codes
status
test_function (void)
{
int r1, r2;
r1 = rand();
r2 = rand();
if (r1 > r2) {
return STATUS_OK;
}
return STATUS_ERR;
}
int
main ()
{
status ret;
srand(time(0));
ret = test_function();
printf("ret is %u\n", ret); // how is this already working ?? %u should expect unsigned int ??
if (ret == STATUS_OK) {
printf("ret is OK\n");
} else {
printf("ret is not OK\n");
}
return 0;
}
A sample runs print the following:
# ./a.out
ret is 200. <== what makes this work ? how is class type getting converted to integer?
ret is not OK
# ./a.out
ret is 100
ret is OK
As a follow up question, is there anything in the status class that I can do to make printf() legitimately work work this way ? This is convenient as I can avoid touching lot of code.
Printf takes the bytes at the beginning of the class and casts them to the specified type ("u") itself, and does not call any class methods, including the () operator.
You can't make your class work with printf by changing only the class, since it's a C language function and not C++, that interprets your class in memory as a simple collection of bytes without any internal structure (void*), i.e. it doesn't call conversion operators to type. Your code works because the class is two consecutive unsigned int fields status_ and sub_status_ . printf, seeing the format flag "u", takes the zero offset of the class field with the size and type of unsigned int, which completely coincides with the status_ field. If you add another field in the class before this field, for example "unsigned int constant_ = 5;", then 5 will always be displayed, since now it will be located at the beginning. If the field size does not match the printf output format or a virtual method table appears in the class, then your output can be anything.
To avoid this, you must explicitly define how to print your class, in order to do this:
use std::cout, in other words replace printf("ret is %u\n", ret); with std::cout << "ret is " << ret << std::endl;
add a public method in the class to get the status code:
unsigned int status_value() const
{
return status_;
}
add a function after the class declaration to define the output of your class to the output stream:
std::ostream& operator<<(std::ostream& stream, const status& s)
{
stream << s.status_value();
return stream;
}
Then you will have a predictable result.
If you want minimal work on your printf calls, you can add only a conversion operator to unsigned int in the class:
operator unsigned int() const
{
return status_;
}
Then you only have to cast your class to unsigned int:
printf("ret is %u\n", (unsigned int)ret);
printf("ret is %u\n", static_cast<unsigned int>(ret));
Or add and use a public method to get the status code:
printf("ret is %u\n", ret.status_value());
printf's %u specifier expects an unsigned int. Passing it a different type as argument (after default argument promotions) causes undefined behavior.
That is the case here.
printf is not extendable. You can either write your own function wrapping printf and interpreting the format string (not recommended) or use std::cout << with overloaded operator<< instead.
Or you can use fmtlib as alternative (also available as <format> in C++20).

Implementing a String class with implicit conversion to char* (C++)

It might not be advisable according to what I have read at a couple of places (and that's probably the reason std::string doesn't do it already), but in a controlled environment and with careful usage, I think it might be ok to write a string class which can be implicitly converted to a proper writable char buffer when needed by third party library methods (which take only char* as an argument), and still behave like a modern string having methods like Find(), Split(), SubString() etc. While I can try to implement the usual other string manipulation methods later, I first wanted to ask about the efficient and safe way to do this main task. Currently, we have to allocate a char array of roughly the maximum size of the char* output that is expected from the third party method, pass it there, then convert the return char* to a std::string to be able to use the convenient methods it allows, then again pass its (const char*) result to another method using string.c_str(). This is both lengthy and makes the code look a little messy.
Here is my very initial implementation so far:
MyString.h
#pragma once
#include<string>
using namespace std;
class MyString
{
private:
bool mBufferInitialized;
size_t mAllocSize;
string mString;
char *mBuffer;
public:
MyString(size_t size);
MyString(const char* cstr);
MyString();
~MyString();
operator char*() { return GetBuffer(); }
operator const char*() { return GetAsConstChar(); }
const char* GetAsConstChar() { InvalidateBuffer(); return mString.c_str(); }
private:
char* GetBuffer();
void InvalidateBuffer();
};
MyString.cpp
#include "MyString.h"
MyString::MyString(size_t size)
:mAllocSize(size)
,mBufferInitialized(false)
,mBuffer(nullptr)
{
mString.reserve(size);
}
MyString::MyString(const char * cstr)
:MyString()
{
mString.assign(cstr);
}
MyString::MyString()
:MyString((size_t)1024)
{
}
MyString::~MyString()
{
if (mBufferInitialized)
delete[] mBuffer;
}
char * MyString::GetBuffer()
{
if (!mBufferInitialized)
{
mBuffer = new char[mAllocSize]{ '\0' };
mBufferInitialized = true;
}
if (mString.length() > 0)
memcpy(mBuffer, mString.c_str(), mString.length());
return mBuffer;
}
void MyString::InvalidateBuffer()
{
if (mBufferInitialized && mBuffer && strlen(mBuffer) > 0)
{
mString.assign(mBuffer);
mBuffer[0] = '\0';
}
}
Sample usage (main.cpp)
#include "MyString.h"
#include <iostream>
void testSetChars(char * name)
{
if (!name)
return;
//This length is not known to us, but the maximum
//return length is known for each function.
char str[] = "random random name";
strcpy_s(name, strlen(str) + 1, str);
}
int main(int, char*)
{
MyString cs("test initializer");
cout << cs.GetAsConstChar() << '\n';
testSetChars(cs);
cout << cs.GetAsConstChar() << '\n';
getchar();
return 0;
}
Now, I plan to call the InvalidateBuffer() in almost all the methods before doing anything else. Now some of my questions are :
Is there a better way to do it in terms of memory/performance and/or safety, especially in C++ 11 (apart from the usual move constructor/assignment operators which I plan to add to it soon)?
I had initially implemented the 'buffer' using a std::vector of chars, which was easier to implement and more C++ like, but was concerned about performance. So the GetBuffer() method would just return the beginning pointer of the resized vector of . Do you think there are any major pros/cons of using a vector instead of char* here?
I plan to add wide char support to it later. Do you think a union of two structs : {char,string} and {wchar_t, wstring} would be the way to go for that purpose (it will be only one of these two at a time)?
Is it too much overkill rather than just doing the usual way of passing char array pointer, converting to a std::string and doing our work with it. The third party function calls expecting char* arguments are used heavily in the code and I plan to completely replace both char* and std::string with this new string if it works.
Thank you for your patience and help!
If I understood you correctly, you want this to work:
mystring foo;
c_function(foo);
// use the filled foo
with a c_function like ...
void c_function(char * dest) {
strcpy(dest, "FOOOOO");
}
Instead, I propose this (ideone example):
template<std::size_t max>
struct string_filler {
char data[max+1];
std::string & destination;
string_filler(std::string & d) : destination(d) {
data[0] = '\0'; // paranoia
}
~string_filler() {
destination = data;
}
operator char *() {
return data;
}
};
and using it like:
std::string foo;
c_function(string_filler<80>{foo});
This way you provide a "normal" buffer to the C function with a maximum that you specify (which you should know either way ... otherwise calling the function would be unsafe). On destruction of the temporary (which, according to the standard, must happen after that expression with the function call) the string is copied (using std::string assignment operator) into a buffer managed by the std::string.
Addressing your questions:
Do you think there are any major pros/cons of using a vector instead of char* here?
Yes: Using a vector frees your from manual memory management. This is a huge pro.
I plan to add wide char support to it later. Do you think a union of two structs : {char,string} and {wchar_t, wstring} would be the way to go for that purpose (it will be only one of these two at a time)?
A union is a bad idea. How do you know which member is currently active? You need a flag outside of the union. Do you really want every string to carry that around? Instead look what the standard library is doing: It's using templates to provide this abstraction.
Is it too much overkill [..]
Writing a string class? Yes, way too much.
What you want to do already exists. For example with this plain old C function:
/**
* Write n characters into buffer.
* n cann't be more than size
* Return number of written characters
*/
ssize_t fillString(char * buffer, ssize_t size);
Since C++11:
std::string str;
// Resize string to be sure to have memory
str.resize(80);
auto newSize = fillSrting(&str[0], str.size());
str.resize(newSize);
or without first resizing:
std::string str;
if (!str.empty()) // To avoid UB
{
auto newSize = fillSrting(&str[0], str.size());
str.resize(newSize);
}
But before C++11, std::string isn't guaranteed to be stored in a single chunk of contiguous memory. So you have to pass through a std::vector<char> before;
std::vector<char> v;
// Resize string to be sure to have memor
v.resize(80);
ssize_t newSize = fillSrting(&v[0], v.size());
std::string str(v.begin(), v.begin() + newSize);
You can use it easily with something like Daniel's proposition

How can I simplify the calling of this function?

I've written (and use) my own string formatting function and I'd like to simplify the usage of the function, in a specific way shown below, but I'm unsure how.
Here's the relevant code:
// Object that can hold a copy of every type I want to print.
// Stores the copy in a union, with an enumeration to identify
// the type. any uses C++ constructors, but could also be implemented
// with C99 designated initializers, like so: https://ideone.com/ElQgBV
struct any
{
...
}
// The string format function requires the variable arguments
// to all be of the 'any' type for type safety and (essential for
// my purposes) positional printing.
// Arguments are accessed with a va_list, so essentially
// the variable arguments are treated as an array of any objects.
char* format_function_(const char* fmt, ...);
// I call the above function with this macro that expands the
// variable arguments and adds a default-constructed sentinel
// at the end. The sentinel is used by the function to count
// how many arguments were passed.
#define format(fmt, ...) format_function_(fmt, __VA_ARGS__, any())
// Calling the function like so, via the above macro...
char* str = format("bits:%4b string:%1 %0 int:%3h float:%2.2\n",
any("world"), any("hello"), any(3.14159f), any(42), any((u8)(1<<4)));
// ...returns this string:
// bits:00010000 string:hello world int:0000002A float:3.14
I'd like to be able to call the function like regular *printf style functions...
char* str = format("bits:%4b string:%1 %0 int:%3h float:%2.2\n",
"world", "hello", 3.14159f, 42, (u8)(1<<4));
...with the use of the any object hidden away, possibly behind another macro.
How can I accomplish this?
Edit/Update The positional arguments are essential for my purposes. Any answer that does not preserve this functionality is not a valid answer.
Since the C++11 standard there's something called parameter packs which makes this very simple:
char* format_function(const char* fmt, ...)
{
...
}
template<typename ...T>
char* format(const char* fmt, T... values)
{
return format_function(fmt, any(values)...);
}
...
char* str = format("bits:%4b string:%1 %0 int:%3h float:%2.2\n",
"world", "hello", 3.14159f, 42, (u8)(1<<4));
Maybe you'ld like something like this? (Alert: C++11 code!)
#include <stdio.h>
inline void format() {}
void format(char ch) {
fputc(ch, stdout);
}
void format(int i) {
if(i < 0) {
fputc('-', stdout);
i = -i;
}
int divider = 1;
while(i / divider >= 10)
divider *= 10;
do {
int digit = i / divider;
i -= divider * digit;
divider /= 10;
fputc('0' + digit, stdout);
} while(divider > 0);
}
void format(const char *str) {
fputs(str, stdout);
}
// TODO: Add more 'format()' overloads here!
template<typename FirstArg, typename... OtherArgs>
inline void format(const FirstArg &first, OtherArgs... others) {
format(first);
format(others...);
}
Then, you can simply...
const char *glorifiedIndex(int index) {
switch(index % 10) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
}
int main(int argc, const char *const argv[]) {
format("Hello, world!\n");
format("My name is ", argv[0], ", and I was given ", argc - 1, " argument", argc != 2 ? "s" : "", ".\n\n");
for(int i = 1; i < argc; i++)
format(i, glorifiedIndex(i), " argument: \"", argv[i], "\"\n");
format("Goodbye, world!\n");
}
This is a more flexible and elegant model, for the following reasons:
Semantically safe.
Type safe.
No <cstdarg> stuff.
No any stuff.
No incredibly badly-designed iostream stuff.
It's too simple to implemet, and I mean too much :). Compare this few lines of code with a typical 3000+ lines long printf.c. The difference is in several orders of magnitude!
You may have nostalgic moments relating with Java and Python.
If you change the type of any expression for whatever reason (i.e, int to unsigned), the function accomodates itself to this.
(Both good and evil) compiler optimizations can kick in easily.
The user of the library may extended the abilities of the format() function by means of overloading it with user-defined types.
This imposibilites the use of dynamic formats (this is intended for obvious security reasons).
This forces you to create special functions for what I call bit-printing, i.e, printing in a machine-parsable way, rather than human-readable as format() did, does, and will do.
You may use overloading features to extend this list yourself :).

C++11 Function That Only Accepts String Literals?

I want to write a C++11 function that will only accept string literals as a parameter:
void f(const char* s) { static_assert(s is a string literal); ... }
That is:
f("foo"); // OK
char c = ...;
f(&c); // ERROR: Doesn't compile
string s = ...;
f(s.c_str()); // ERROR: Doesn't compile
etc
Is there anyway to implement this? The signature of the function is open to changes, as is adding the use of macros or any other language feature.
If this is not possible what is the closest approximation? (Can user-defined literals help in anyway?)
If not is there a platform specific way in GCC 4.7 / Linux ?
I think the closest you are going to get is this
template<int N>
void f(const char (&str)[N]){
...
}
It will compile with literals and arrays but not pointers.
An alternative might be to make a GCC extension to check at compile time that your particular function is only called with a literal string.
You could use MELT to extend GCC. MELT is a high-level domain specific language to extend the GCC compiler, and is very well suited for the kind of check you want.
Basically, you would add a new pass inside GCC and code that pass in MELT which would find every gimple which is a call to your function and check that the argument is indeed a literal string. The ex06 example on melt-examples should inspire you. Then subscribe to gcc-melt#googlegroups.com and ask your MELT specific questions there.
Of course, this is not a foolproof approach: the function could be called indirectly thru pointers, and it could e.g. have a partial literal string, e.g. f("hello world I am here"+(i%4)) is conceptually a call with some literal string (e.g. in .rodata segment), but not in the generated code nor in the gimple.
I use this :
// these are used to force constant, literal strings in sqfish binding names
// which allows to store/copy just the pointer without having to manage
// allocations and memory copies
struct _literalstring
{
// these functions are just for easy usage... not needed
// the struct can be empty
bool equal(_literalstring const *other) { return !strcmp((const char *)this, (const char *)other); }
bool equal(const char *other) { return !strcmp((const char *)this, other); }
const char *str(void) { return (const char *)this; }
bool empty(void) { return *(const char *)this == 0; }
};
typedef _literalstring *LITSTR;
constexpr LITSTR operator "" _LIT(const char *s, size_t) {
return (LITSTR)s;
}
Then you just declare your function like this :
void myFunc(LITSTR str)
{
printf("%s\n", str->str());
printf("%s\n", (const char *)str);
const char *aVar = str->str();
const char *another = (const char *)str;
}
And you call it like this:
myFunc("some text"_LIT);
If you do something like this:
myFunc("some text");
myFunc(aTextVariable);
you get a compiler error.

C++: Define simple constant for use?

In C++ I wanted to define a constant that I can use in another function, A short answer on how to do this will be fine..
Lets say at the beginning of my code I want to define this constant:
//After #includes
bool OS = 1; //1 = linux
if (OS) {
const ??? = "clear";
} else {
const ??? = "cls";
}
I don't know what type to use to define the "clear" string... I'm so confused.
Later on I want to use it within a function:
int foo() {
system(::cls); //:: for global
return 0;
}
How would I define the string up top, and use the string down below? I heard char only had one character and things... I'm not sure how to use , since it says it's converting string into const char or something.
char* isn't quite a char. char* is basically a string (it's what strings were before C++ came along).
For illustration:
int array[N]; // An array of N ints.
char str[N]; // An array of N chars, which is also (loosely) called a string.
char[] degrades to char*, so you'll often see functions take a char*.
To convert std::string to const char*, you can simply call:
std::string s;
s.c_str()
In this case, it's common to use the preprocessor to define your OS. This way you can use the compiler to do the platform specific stuff:
#ifdef OS_LINUX
const char cls[] = "clear";
#elif OS_WIN
const char cls[] = "cls";
#endif
One thing you may want to consider is making it a function. This avoids nasty dependencies of global construction order.
string GetClearCommand() {
if (OS == "LINUX") {
return "clear";
} else if (OS == "WIN") {
return "cls";
}
FAIL("No OS specified?");
return "";
}
What it looks like you're trying to do is this:
#include <iostream>
using namespace std;
#ifdef LINUX
const char cls[] = "LINUX_CLEAR";
#elif WIN
const char cls[] = "WIN_CLEAR";
#else
const char cls[] = "OTHER_CLEAR";
#endif
void fake_system(const char* arg) {
std::cout << "fake_system: " << arg << std::endl;
}
int main(int argc, char** argv) {
fake_system(cls);
return 0;
}
// Then build the program passing your OS parameter.
$ g++ -DLINUX clear.cc -o clear
$ ./clear
fake_system: LINUX_CLEAR
Here's the problem, you're suffering from going out of scope with the variables. If I declare something within brackets, it only exists within the brackets.
if( foo ){
const char* blah = "blah";
}
Once we leave the if statement, the variable blah disappears. You'll need to instantiate it non-locally to whatever brackets you write. Hence:
void Bar(){
const char* blah = "blah";
if( foo ){
//blah exists within here
}
}
However, blah will not exist outside of Bar. Get it?
Yet another option is to create a class with a bunch of static methods. Create a new method for each command. Something like:
// in sys-commands.h
class SystemCommands {
public:
static char const* clear();
static char const* remove();
};
This gives you a few nice options for the implementation. The nicest one is to have a separate implementation file for each platform that you select during compile time.
// in sys-commands-win32.cpp
#include "sys-commands.h"
char const* SystemCommands::clear() { return "cls"; }
char const* SystemCommands::remove() { return "erase /f/q"; }
// in sys-commands-macosx.cpp
#include "sys-commands.h"
char const* SystemCommands::clear() { return "/usr/bin/clear"; }
char const* SystemCommands::remove() { return "/bin/rm -fr"; }
Which file gets compiled will determine which command set will be used. Your application code will look like:
#include <cstdlib>
#include "sys-commands.h"
int main() {
std::system(SystemCommands::clear());
return 0;
}
Edit: I forgot to mention that I prefer static functions to global constants for a bunch of reasons. If nothing else, you can make them non-constant without changing their types - in other words, if you ever have to select the command set based on runtime settings, the user code does not have to change or even be aware that such a change occurred.
You can use a common header file and link to different modules depending on the systen:
// systemconstants.hpp
#ifndef SYSTEM_CONSTANTS_HPP_INCLUDED
#define SYSTEM_CONSTANTS_HPP_INCLUDED
namespace constants {
extern const char cls[]; // declaration of cls with incomplete type
}
#endif
In case of Linux, just compile and link to this one:
// linux/systemconstants.cpp
#include "systemconstants.hpp"
namespace constants {
extern const char cls[] = "clear";
}
In case of Windows, just compile and link to this one:
// windows/systemconstants.cpp
#include "systemconstants.hpp"
namespace constants {
extern const char cls[] = "cls";
}
System-specific translation units could be placed in specific subdirectories (linux/, windows/, etc) of which one could be automatically selected during the build process. This extends to many other things, not just string constants.