Showing posts with label memo. Show all posts
Showing posts with label memo. Show all posts

Wednesday, October 6, 2010

Did you know? Funny facts about C99

I am currently writing an implementation of the C99 programming language as a basic language for the MPS language workbench. I call this implementation c-base, because it is intended to be used as a target language for code generation, much like MPS' Java-like base-language.

I created the model of this MPS language according to the C99 standard grammar. Thus, I had to dive into its documentation and I have found a number of surprising features and properties of the C99 programming language. Not all of them are important, but if you want to be nitpicker in the next C discussion, here is your ammo ;-)

So, did you know, that

Wednesday, March 3, 2010

When new features collide with old syntax


My C++ times are over. But Roker keeps on feeding me with input. And I could not let this one go by unnoticed.
To make it short, what do you think does the following program print?
#include <iostream>

struct X { };

class Y {
public:
    Y (const X& x) {
        std::cout << "fnord" << std::endl;
    }
};

int main() {
    Y d(X());
    return 0;
}
At first sight it looks like everything is ok. We know that references to temporaries must be const, which is the case here. So we think, d is going to be a Y object which was initilized with a temporary X object. In this case, the program should output "fnord".
But it doesn't. Instead it prints nothing. Mysterious you think? So did I. So I started debugging the issue while Roker was giggling. So, if d is not a Y object, what is it then? Let's ask the compiler and the C++ runtime:
#include <typeinfo>
//...
int main() {
    Y d(X());
    std::cout << typeid(d).name() << std::endl;
    return 0;
}
The program now prints "F1YPF1XvEE". Hmm, I can not decrypt this, can you? We need to demangle the name in order to see it's real C++ nature:
$ c++filt -t F1YPF1XvEE
Y ()(X (*)())
Who can decrypt this? If you can't, here is a howto on reading C type declarations, because the unfamiliar syntax for function types is a C heritage. And what does this type mean after all? It means, that d is a function which returns a Y object and expects a pointer to a function which returns a X object and expects nothing. Got it? If not, here is how I would write it, in case I would need such a type:
#include <iostream>
#include <typeinfo>

struct X { };
class Y { /*...*/ }; 

typedef X (Inner)();
typedef Y (Outer)(Inner);

int main()
{
    Outer d;
    std::cout << typeid(d).name() << std::endl;
    return 0;
}
This program prints Y ()(X (*)()) which is the type of d from the original program. Ok, so now we know, what the program does. It declares a function. That's why there is no X object ever created. So, although the code could mean what we originally intended, the compiler chooses to understand something else, which is also possible due to the C syntax rules. Although I still don't know what function declarations inside other functions are good for, the compiler again prefers them. Anyway, what's the C way of removing ambiguity from syntax? Right, it's parantheses:
//...
int main()
{
    Y o((X()));
    std::cout << typeid(o).name() << std::endl;
    return 0;
}
Now, the program prints "fnord" and "1Y" which is the mangled name for the type Y. To sum it up, this is yet another example for why I consider the C heritage to be a major source of trouble for C++ developers. The C syntax was never designed for temporary variables and combining both yields to what we have seen here: ambiguity, ugly workarounds and surprise and furstration for the developer. Don't get me wrong, though. I still think that C++ could hardly have been made better given the design goals which where taken those days. I truly have a love-hate for that language.

Sunday, February 21, 2010

Trust your tools...

For my current work I need to show how efficient the generated code is. Fortunately the binutils include a tool called size which "lists the section sizes of an object or archive file".
In order to have representative results I should compile for a platform which is typical for the WSN community. I have chosen the MSP430 because there is a package of a GCC cross compiler for that target in the TinyOS Ubuntu repository.
At first, the numbers looked promising. But at a closer look something was wrong. Investigating the problem emerges something weird.

Friday, January 22, 2010

xtc, meta-models and static typing

For my current work I want to implement a C* to C compiler, where * stands for a yet unknown set of extensions and restrictions.

In my opinion, parsing expression grammars are the tool of choice for growing a grammars. Among the existing PEG tools, the Rats! parser generator of the eXTensible C framework offers the most. Besides many handy features there is a complete C grammar and a pretty printer. Ready to take off!

Monday, November 9, 2009

C++ pitfalls

As I do no C++ hacking at ETH I have not stumbled upon new input for this blog on my own. So I am very happy that Roker keeps on feeding me.

Today he pointed me at Cay Horstmann's list of C++ pitfalls. Some of the issues have already been covered here but some haven't. I recommend reading it to every C++ developer as this takes less time than learning it the hard way by debugging code. Have fun.

Concerning the iterator issues Cay provides a Safe STL implementation which is supposed to be used as a drop in replacement for the STL during development. It adds state and knowledge about the owner to iterators and uses this information to do runtime checks. If you accidently use your iterators in a wrong way you end up with a comprehensive runtime error instead of a segfault "deep in the bowels of STL code".

I haven't tested Safe STL. If anybody did feel free to send me your experience. I would be glad to blog about it.

Catching Integer Overflows in C


Roker pointed me to an article about Catching Integer Overflows in C by Felix von Leitner. It covers some nasty pitfalls of integer arithmetic in C. My absolute favourite is that abs may return a negative number. Comforting to know that C++ inherited this behaviour.... 

Friday, October 23, 2009

TLS/SSL

Since 2008, MD5 is considered broken. Consequently GnuTLS refuses signatures of certificates if they were made with MD5. That's why since my latest Debian upgrade, msmtp, which uses libgnutls, has not been able to establish a checked TLS session with the SMTP server.

Thursday, July 9, 2009

Feature collision


One thing the C++ community is pretty proud of is that, in contrast to C, C++ supports const correctness. Turns out that const correctness clashes with STL containers.
Today Roker pointed me to a poor guy from #c++@freenode with the following problem:

#include <iostream>
#include <list>

typedef std::list<int> list_t;

list_t::const_iterator find_first_odd(const list_t & list)
{
  for (list_t::const_iterator i = list.begin(); i != list.end(); ++i)
  {
    if (*i % 2 != 0) return i;
  }

  return list.end();
}

int main()
{
  list_t list;
  list.push_back(2);
  list.push_back(3);
  list.push_back(4);

  list_t::const_iterator odd_i = find_first_odd(list);

  if (odd_i != list.end())
    // Error. Can not use const_iterator with 'std::list::erase'
    list.erase(odd_i);

  return 0;
}

For the sake of const correctness the function find_first_odd expects a constant reference to the list because it is not going to modify it. But as a result the function can only return a const_iterator, because there is no way to get a non-const iterator from the constant list.
So the caller of find_first_odd ends up with a const_iterator which is useless for modifying operations such as erase. And for him it is also impossible to turn the const_iterator into a non-const iterator. The two types have no relation to each other, so casting does not work. And there are no conversion functions in the STL either. So the only way out here is to sacrifice const correctness and pass a non-const reference to find_first_odd.
According to Roker nobody on #c++ had a better solution. And according to Scott Meyers' article Three Guidelines for Effective Iterator Usage there is none. const_iterators can not be easily transformed into iterators. What you can do is nasty and rather inefficient.
Here it comes:

template <class Container>
typename Container::iterator convert(typename Container::const_iterator in, Container& container)
{
    typename Container::iterator out(container.begin());
    std::advance(out, std::distance<typename Container::const_iterator>(out, in));
    return out;
}

If the container does not support random access, this conversion is O(n). Furthermore it can only be done, if the container object is at hand. Finally note, that this function violates const correctness, because the container object which is not altered by the function is not passed as const&. The reason is that the begin() function of a constant container returns a const_iterator which you can not convert into the output non-const iterator. In case you are confused, try this illustration.

Wednesday, July 8, 2009

Parsing Expression Grammars

Parsing Expression Grammar (PEG) is a rather new class of grammars for formal languages. The foundations date back to 1973 and come from "Parsing algorithms with backtrack" by Alexander Birman and Jeffrey D. Ullman. But in those days the approach was considered as not being practical because of limited memory resources. In 2002 Bryan Ford revived the topic in his master's thesis Packrat Parsing: a Practical Linear-Time Algorithm with Backtracking by turning the theoretical model into an equivalent, but practical one. Since then the topic has been gaining more and more attraction and additional publications followed. Bryan is collecting the - in his mind - important ones on a PEG homepage.

Thursday, July 2, 2009

Model-driven Software Development

It seems that the Software Engineering Podcast is going to keep me busy for a while. For me it is a valuable source of knowledge. I had no idea that I have no idea about software engineering ;-)

Friday, June 26, 2009

Tuesday, June 23, 2009

Patterns

Chippy, a friend of mine, pointed me to the Heise developer SoftwareArchitekTOUR podcast (german), especially to the episode one about the usage of patterns. Chippy is a former colleague and at that time we were discussing a lot about pattern driven software architectures and code generation.

Wednesday, April 29, 2009

network boot

Some of my fellows here are working on the Web Of Things. Currently they are planing to setup a playground in the office of our group. For the gateways Dominique decided to use MicroClient Sr. machines, which are tiny VIA based ultra low power PCs.

I suggested to boot and run them completely from the network. This saves money as no local storage devices have to be bought. And it eases administration as there is only one centralized image one has to maintain. I promised to explain him how it works, so here it goes.

Thursday, April 16, 2009

domain specific languages

As I wanted to obtain a deeper understanding on how code generation, DSLs and programming languages in general are related to each other I started to research. I found a lot of publications on DSLs from various authors and companies.

One of those authors is Martin Fowler who is writing a DSL book and has written a great article about what he calls Language Workbenches, a vision of an IDE which inherently operates with and on DSLs.

Wednesday, March 18, 2009

posix file access control lists

Finally I have found a good article about POSIX file access control lists. I have been trying to understand their usage by just reading the manual pages of setfacl and getfacl but I have always been missing the big picture. Now I got it.

Tuesday, March 17, 2009

full disc encryption

Full disc encryption is something you definitely want to have. No need to worry about private data on a stolen or old hard disc. Everything is encrypted. And the performance penalties are arguable meaning that most user would not notice any difference.

sshfs

The linux category will be about tools, applications and techniques I encounter on my work with the linux desktop and server. The main reason for me blogging this is that as time goes by I tend to forget names and details. In future I can look-up them here. And maybe others will find it interesting, too.

Since version 2.6.14 the linux kernel has Filesystem in Userspace (FUSE) support. Among others, one such file system in user space is sshfs.

Friday, February 20, 2009

Boost.Build

Recently I stumbled over Boost.Build which is a build system for C++ projects.

Boost.Build is based on FT Jam which in turn is based on Perfoce Jam. I don't know, which feature has been added by whom. Nevertheless what Boost.Build offers you is really what you ever wanted as a C++ developer.

Sunday, February 15, 2009

C Traps


Quite a time ago Andrew König has written a book about C traps and pitfalls. Today, Roker pointed me on an earlier technical report which was the basis of the book.
Although some things are different with C++, I recommend everybody to read at least the report. Otherwise you surely will stumble on those items sooner or later.