Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
First thing, I am not looking for a tool that is going to produce an unmaintainable C code from an existing cpp code-base. It is a requirement from a client, so I cannot just use the CPP code base itself.
I am trying to work out a work-flow, so that I can convert the code-base from CPP to C incrementally without breaking the code. I have thought out a few things using the "extern C" approach
Classes to Structs
Member functions of the Classes will be converted to Struct_name_FunctionName format.
In case of a function being re-used by 2 classes, I plan to use function pointers.
Replace overloaded operators like +,- etc with actual functions. Eg a Add_, Sub_ etc
Can you folks add anymore ?
and point out potential pit-falls ?
I cannot share the code-base because of NDA.
The code base isn't huge in itself. Its got around 50 cpp files, saw some 100 odd classes.
Thanks in advance.
P.s I have gone through some other questions that sound similar. But they don't really have the work-flow that I am looking for.
[Closing] : Although the post has been put on hold because it is too broad, many of the comments were in fact useful. I am clearer on what needs to be done than before. Thank you.
Well, there's a very long list you'll have to tackle. Without claiming to be complete, you also need:
Virtual function support (not impossibly hard, function pointer table)
Constructors and destructors (Reasonable mapping to ordinary functions, lot of work)
Exceptions and stack unwinding (extremely hard)
Missing C++ library functions and classes (lot of work)
But don't kid yourself. std::map<std::string, std::pair<int, int>> is a very straightforward class that stores two ints for each string. The C translation of that class is an outright mess. MyMap["five,three"] = std::make_pair(5,3) can easily become 100+ lines of C code.
If your C++ code makes extensive use of OO constructs - particularly inheritance and polymorphism - you might wish to look at some C libraries that mimic this in C. qobject (from the qemu source tree) is one I know well, but better known (to nearly everyone bar me) is http://en.wikipedia.org/wiki/GObject which comes from glib. Nowadays, that isn't tied up with GUI code.
The advantage here is that you can change the language in use without making too many changes to the program flow.
glib also provides a fair number of other useful library constructs.
Following the advice to take the GObject as an example how C++-like code is done in C, there's one thing you can try out:
Translate the C++ code to Vala
Generate C code from Vala compiler.
Vala is a C#-like language; except that you'll have to repeat "public" or "private" in every function signature, as well as get rid of pointer-star in class types in use, there's no much things you'll have to do.
Of course, the generated C code will look the same ugly as from the other generators, but at least there are some short ways how to make it a "maintainable" code (the main problem is that every object created in Vala results in incrementing reference counter in C code, which isn't always necessary).
The GObject model can be a nice instruction/example as to how to translate C++ constructs into the same in C. If you don't use exceptions (Vala does! :) ), there should be no trouble with that. Of course the main guidelines are:
Normal methods: use the pointer to object as first argument. The function name is NAMESPACE_CLASSNAME_METHODNAME.
Virtual methods: you have to create a "characteristic object", pointed by the "object" of that class, which contains pointers to functions. The class's characteristic objects are usually created in GObject in functions that return pointer to that object - the object itself is lazily created and saved in a static local variable.
Overloading: add name-distinguising parts (Vala does not support overloading, even in constructors - constructors use special syntax for calling named constructors)
Templates: expand in place :)
Derivation: single derivation only (as in Vala as well), make the first field of the "derived class" structure the field of type of the "base class" structure.
Calling methods from base classes: use C cast. If you follow the point 5, you should simply cast the structure of derived class object to the structure of the base class.
Related
For fun I have been working on my own programming language that compiles down to C++. While most things are fairly straightforward to print, I have been having trouble compiling my golang style interfaces to c++. In golang you don't need to explicitly declare that a particular struct implements an interface, it happens automatically if the struct has all the functions declared in the interface. Originally I was going to compile the interfaces down to a class with all virtual methods like so
class MyInterface {
public:
void DoSomthing() = 0;
}
and all implementing structures would simply extend from the interface like you normally would in c++
class MyClass: public MyInterface {
// ...
}
However this would mean that my compiler would have to loop over every interface defined in the source code (and all dependencies) as well as every struct defined in the source and check if the struct implements the interface using an operation that would take O(N*M) time where N is the number of structs and M is the number of interfaces. I did some searching and stumbled upon some c++ code here: http://wall.org/~lewis/2012/07/23/go-style-interfaces-in-cpp.html that makes golang style interfaces in c++ a reality in which case I could just compile my interfaces to code similar to that (albeit not exactly since I am hesitant to use raw pointers over smart pointers) and not have to worry about explicitly implementing them. However the author states that It should not be done for production code which worries me a little.
This is kinda a loaded question that may be a little subjective, but could anyone with more C++ knowledge tell me if doing it the way suggested in the article is a really bad idea or is it actually not that bad and could be done, or if there is a better way to write c++ code that would allow me to achieve the behavior I want without resorting to the O(N*M) loop?
My initial thought is to make use of the fact that C++ supports multiple inheritance. Decompose your golang interface into single-function interfaces. Hash all interfaces by their unique signature. It now becomes an O(N) operation to find the set of C++ abstract interfaces for your concrete classes.
Similarly, when you consume an object, you find all the consumed interfaces. This is now O(M) by the same logic. The total compiler complexity then becomes O(N)+O(M) instead of O(N*M).
The slight downside is that you're going to have O(N) vtables in C++. Some of those might be merged if certain interfaces are always groupd together.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Using a struct we can achieve all the functionality of a class: constructors (that can be modified/overloaded), destructors (that can be modified/overloaded), operator overloading, instance methods, static methods, public/private/protected fields/methods.
Why do we need class then?
Note: I don't want the answer saying that in struct, fields/methods are public by default.
You don't need classes, the language just gives you another option to choose from. Technically, you're right, you can achieve anything a class can do with a struct.
Besides the default access level, there's also the meaning most programmers associate with the two - struct generally means a light-weight, typically POD, data-type with little to no functionality. A class is usually associated with something bigger.
As Tal Pressman answered at When should you use a class vs a struct in C++?:
From the C++ FAQ:
The members and base classes of a struct are public by default, while in class, they default to private. Note: you should make your base classes explicitly public, private, or protected, rather than relying on the defaults.
struct and class are otherwise functionally equivalent.
OK, enough of that squeaky clean techno talk. Emotionally, most developers make a strong distinction between a class and a struct. A struct simply feels like an open pile of bits with very little in the way of encapsulation or functionality. A class feels like a living and responsible member of society with intelligent services, a strong encapsulation barrier, and a well defined interface. Since that's the connotation most people already have, you should probably use the struct keyword if you have a class that has very few methods and has public data (such things do exist in well designed systems!), but otherwise you should probably use the class keyword.
http://www.parashift.com/c++-faq-lite/classes-and-objects.html#faq-7.8
I think one addition to this reason could be that C already had structs. When Bjarne Stroustrup designed C++, he wanted to add classes with all the functionalities you listed in your original question, features which were not present in C. When implementing those features, he probably realised it didn't make sense to make two separate implementations for struct and class (except the public/private default visibility).
TL/DR: in C++ structs/classes describe the intent of the programmer to have POD or more complex abstractions, and the introduction of the class keyword is probably here for historical reasons (add an additional keyword in order to create featurefull classes, then backport those features into the struct keyword because it's more pragmatic to implement).
class is simply the commonly accepted name in OO for a type used for instantiating objects. When introducing the OO paradigm in C++, it was deemed less surprising to use class instead of struct.
struct was kept to maximize backwards compatibility with C.
Today's usage of the two is in line with this : struct is most commonly used for C-style POD types, while class is used for the OO concept of classes.
To make a long story short, class really wasn't needed at all. It changes the defaults to ones that are arguably safer and more applicable to OO programming, but you could use a struct (as defined by C++) for any place that you currently use a class (if you wanted to get cute and meta about it, you could call struct a base class of class that satisfies the LSP).
At the same time, misunderstanding of struct in C++ is rampant, and class fits the intended concept enough better that it's often much easier to explain. New users often seem to find it at least marginally more understandable -- a reasonable goal in itself.
There are no such difference between C++ struct and C++ class, you can perform almost all the functions with struct as you can do with class, but struct is a C keyword which gradually got modified/evolved in C++ and named as class. A we are in C++, it is better to use class rather than struct.
Take an example, if you have done some coding in C++ and some person who works in Java came after 2 months to review your code, which one will he find comfortable to understand a code with "struct" or a code with "class"?
Is it possible to extend a class from a C++ library without the source code? Would having the header be enough to allow you to use inheritance? I am just learning C++ and am getting into the theory. I would test this but I don't know how.
Short answer
YES, definitively you can.
Long answer:
WARNING: THe following text may hurt children an sensitive OOP integralists. If you feel or retain to be one of such, stay away from this answer: mine your and everyone alse life will be more easier
Let me reveal a secret: STL code is just nothing more than regular C++ code that comes with headers and libraries, exactly like your code can -and most likely- do.
STL authors are just programmer LIKE YOU. They are no special at all respect to the compiler. Thay don't have any superpower towards it. They sits on their toilet exacly like you do on yours, to do exactly what you do. Don't over-mistify them.
STL code follows the exact same rules of your own written code: what is overridden will be called instead of the base: always if it is virtual, and only according to the static type of its referring pointer if it is not virtual, like every other piece of C++ code. No more no less.
The important thing is not to subvert design issues respecting the STL name convention and semantics, so that every further usage of your code will not confuse people expectation, including yourself, reading your code after 10 years, not remembering anymore certain decisions.
For example, overriding std::exception::what() must return an explanatory persistent C string, (like STL documentation say) and not add unexpected other fuzzy actions.
Also, overriding streams or streaming operators shold be done cosidering the entire design (do you really need to override the stream or just the streambuffer or just add a specific facet to the locale it imbued?): In other words, study not just "the class" but the design of all its "world" to properly understand how it works with what is around.
Last, but not least, one of the most controversial aspect are containers and everything not having virtual destructors.
My opinion is that the noise about the "classic OOP rule: Dont' derive what has no virtual destructor" is over-inflated: simply don't expect a cow to became an horse just because you place a saddle on it.
If you need (really really need) a class that manage a sequence of character with the exact same interface of std::string that is able to convert implicitly into an std::string and that has something more, you have two ways:
do what the good good girls do, embed std:string and rewrite all its 112 (yes: they are more than 100) methods with function that do nothing more than calling them and be sure you come still virgin to the marriage with another good good boy programmer's code, or ...
After discover that this takes about 30 years and you are risking to become 40 y.o. virgin no good good boy programmer is anymore interested in, be more practical, sacrifice your virginity and derive std::string. The only thing you will loose is your possibility to marry an integralist. And you can even discover it not necessarily a problem: you're are even staying away from the risk to be killed by him!
The only thing you have to take care is that, being std::string not polymorphic your derivation will mot make it as such, so don't expect and std::string* or std::string& referring yourstring to call your methods, including the destructor, that is no special respect every other method; it just follow the exact same rules.
But ... hey, if you embed and write a implicit conversion operator you will get exactly that result, no more no less!
The rule is easy: don't make yourself your destructor virtual and don't pretend "OOP substitution principle" to work with something that is not designed for OOP and everything will go right.
With all the OOP integralist requemscant in pacem their eternal sleep, your code will work, while they are still rewriting the 100+ std::string method just to embed it.
Yes, the declaration of the class is enough to derive from it.
The rest of the code will be picked up when you link against the library.
Yes you can extend classes in standard C++ library. Header file is enough for that.
Some examples:
extending std::exception class to create custom exception
extending streams library to create custom streams in your application
But one thing you should be aware is don't extend classes which does not have a virtual destructor. Examples are std::vector, std::string
Edit : I just found another SO question on this topic Extending the C++ Standard Library by inheritance?
Just having an header file is enough for inheriting from that class.
C++ programs are built in two stages:
Compilation
Compiler looks for definition of types and checks your program for language correctness.This generates object files.
Linking
The compiled object files are linked together to form a executable.
So as long as you have the header file(needed for compilation) and the library(needed for linking) You can derive from a class.
But note that one has to be careful whether that class is indeed meant for inheritance.
For example: If you have a class with non virtual destructor then that class is not meant for inheritance. Just like all standard library container classes.
So in short, Just having a interface of class is enough for derivation but the implementation and design semantics of the class do play an important role.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
Coming from a Java background it is new for me to deal with the choice of creating a class or just implementing the functions I might need. Normally this is no question when it comes to modeling something which could have a state.
Now I am implementing a shared library which has no main function and exclusively static member functions. Does something speak against creating a class to encapsulate the functions?
Further I wanted to encapsulate further code, especially auxillary functions, in another file. The execute code is always the same and the state of it does not change, so I guess I would declare them also static - so the same questions arises here to.
If you find you have a class where every method is static, then perhaps a namespace would be more appropriate.
Frankly, this is philosophical, and kind of fuzzy guidelines, but I prefer to use the simplest things first then build up in terms of complexity when its needed.
My first preference is
Free, stateless, side-effect free functions that perform some operations/calculations/transformations on their arguments and return the result(s).
However, if any of those arguments evolve to become stateful, and your function become in charge of maintaining that state, consider wrapping stateful data and methods that manipulate that data into a class for good encapsulation/data hiding.
File I/O is an example of something that's stateful. You open a file, write some data to it which moves ahead a write pointer, and ultimately close it, its a good example of where you'd want a class.
The most obvious example of a place where a free functions are best are math. Other examples might be performing a regex, transforming one kind of message into another kind, etc.
(1) Is simplest because in its purest form there's no persistent state, everything is transformational, and you should consistently get the same output with the same input. Easy to test, easy to figure out how it works. Ideally we wouldn't need to persist any state and we could all program this way.
(2) Is needed because safely updating state is a necessary part of life and if you can't do any data hiding or encapsulation you lose confidence that state is being maintained correctly and safely.
You may want to define a namespace instead of a class.
namespace mycode
{
//Code for the library here
void myfunction()
{
//function definition
}
}
then when you need to use it you can either preface it or use the namespace
mycode::myfunction()
or
using mycode;
myfunction();
Not sure if I completely understand you but yes you can create a container class that provides static methods. It may be worthwhile to make the constructors private to prevent people from instantiation an instance of the class.
class HelperFunctions
{
public:
static void DoSomethingUseful() { /* useful bits */ }
// yata yata
private:
HelperFunctions(); // private default constructor
HelperFunctions(const HelperFunctions&); // private copy constructor
};
Then you could do something like this:
HelperFunctions::DoSomethingUseful();
But you couldn't do something like this:
HelperFunctions myHelperFunction; // private constructor = compile error
You also could create namespaces for the purpose of organization non-member functions.
namespace HelperFunctions
{
void DoSomethingUseful() { /* useful bits */ }
// yata yata
}
Remember you can define namespaces across multiple files as well making these particular useful for grouping objects and functions wherever they may be. This is preferable as it logically separates the functions making the design and intended use more obvious
Unlike Java where everything is a method in C++ we can have functions at a global, namespace, or member scope. You also can have non-member friend functions which can access internal members of a class without being a member of the class themselves.
Basically you can do whatever you want including shoot yourself in the foot.
Edit: Why so serious?
I wasn't suggesting what the OP should or shouldn't do. It seemed as though they were new to C++ coming from the Java world where everything is a method and all "functions" are class members. To that affect my answer was to show how firstly you can create something in C++ similar to what you might have in Java and secondly how you can do other things as well and why that is.
As others have stated it's considered good practice to prefer non-member non-friend functions when possible for various reasons. I agree if you do not need an object with state than you probably shouldn't design one. However I'm not sure if the OP was looking for a philosophical discussion on best practice in design and implementation or just a curiosity for equivalent C++.
I had hoped my last line joking about shooting yourself in the foot was enough to make the point that "just because you can, doesn't mean you should" but perhaps not with this crowd.
Actually, if the code does not belong in a class, you should not put it in a class in C++. That is, one should prefer non-friend non-member functions to member and friend functions. The reason is that pulling the method out of the class results in better encapsulation.
But don't take my word for it, see Scott Meyers' Effective C++ Item #23: Prefer non-member non-friend functions to member functions.
Careful, in C++, static functions are functions that are only visible to other functions in the same file. So basically they are auxiliary functions that cannot be part of the interface of a library.
Static methods in classes is something completely different (even though the same keyword is used in both cases). They are just like normal functions that can call protected/private methods in the same class. You can think of static methods as simple (non-static) functions that are "friends" with the class.
As for the general guideline, I don't think it matters if you have (non-static) functions or static methods as the interface of your library, this is mostly a matter of syntax: call f() or call obj::f(). You can also use namespaces for encapsulation. In this case the syntax is: ns::f() for a function and ns::obj::f() for a static method.
EDIT: Ok, I though there was a confusion around the keyword static, turns out this is more of a controversial answer than I would have wanted it to be. I personally prefer the term method for member functions (which is also the same vocabulary used in the actual question). And when I said static methods can call private methods I was referring to visibility (a.k.a. access control).
I was reading the GoF book and in the beginning of the prototype section I read this:
This benefit applies primarily to
languages like C++ that don't treat
classes as first class objects.
I've never used C++ but I do have a pretty good understanding of OO programming, yet, this doesn't really make any sense to me. Can anyone out there elaborate on this (I have used\use: C, Python, Java, SQL if that helps.)
For a class to be a first class object, the language needs to support doing things like allowing functions to take classes (not instances) as parameters, be able to hold classes in containers, and be able to return classes from functions.
For an example of a language with first class classes, consider Java. Any object is an instance of its class. That class is itself an instance of java.lang.Class.
For everybody else, heres the full quote:
"Reduced subclassing. Factory Method
(107) often produces a hierarchy of
Creator classes that parallels the
product class hierarchy. The Prototype
pattern lets you clone a prototype
instead of asking a factory method to
make a new object. Hence you don't
need a Creator class hierarchy at all.
This benefit applies primarily to
languages like C++ that don't treat
classes as first-class objects.
Languages that do, like Smalltalk and
Objective C, derive less benefit,
since you can always use a class
object as a creator. Class objects
already act like prototypes in these
languages." - GoF, page 120.
As Steve puts it,
I found it subtle in so much as one
might have understood it as implying
that /instances/ of classes are not
treated a first class objects in C++.
If the same words used by GoF appeared
in a less formal setting, they may
well have intended /instances/ rather
than classes. The distinction may not
seem subtle to /you/. /I/, however,
did have to give it some thought.
I do believe the distinction is
important. If I'm not mistaken, there
is no requirement than a compiled C++
program preserve any artifact by which
the class from which an object is
created could be reconstructed. IOW,
to use Java terminology, there is no
/Class/ object.
In Java, every class is an object in and of itself, derived from java.lang.Class, that lets you access information about that class, its methods etc. from within the program. C++ isn't like that; classes (as opposed to objects thereof) aren't really accessible at runtime. There's a facility called RTTI (Run-time Type Information) that lets you do some things along those lines, but it's pretty limited and I believe has performance costs.
You've used python, which is a language with first-class classes. You can pass a class to a function, store it in a list, etc. In the example below, the function new_instance() returns a new instance of the class it is passed.
class Klass1:
pass
class Klass2:
pass
def new_instance(k):
return k()
instance_k1 = new_instance(Klass1)
instance_k2 = new_instance(Klass2)
print type(instance_k1), instance_k1.__class__
print type(instance_k2), instance_k2.__class__
C# and Java programs can be aware of their own classes because both .NET and Java runtimes provide reflection, which, in general, lets a program have information about its own structure (in both .NET and Java, this structure happens to be in terms of classes).
There's no way you can afford reflection without relying upon a runtime environment, because a program cannot be self-aware by itself*. But if the execution of your program is managed by a runtime, then the program can have information about itself from the runtime. Since C++ is compiled to native, unmanaged code, there's no way you can afford reflection in C++**.
...
* Well, there's no reason why a program couldn't read its own machine code and "try to make conclusions" about itself. But I think that's something nobody would like to do.
** Not strictly accurate. Using horrible macro-based hacks, you can achieve something similar to reflection as long as your class hierarchy has a single root. MFC is an example of this.
Template metaprogramming has offered C++ more ways to play with classes, but to be honest I don't think the current system allows the full range of operations people may want to do (mainly, there is no standard way to discover all the methods available to a class or object). That's not an oversight, it is by design.