Archive

Archive for the ‘c/c++’ Category

icc 11.1.059 on ubuntu 9.10

November 3rd, 2009 No comments

ICC und Ifort gibt es non-commercial for free: http://software.intel.com/en-us/articles/non-commercial-software-download/

Unter Ubuntu 9.10 ist die Installation etwas hagelig. Hier eine kleine Hilfestellung:

Es werden trotz Intel64 Installation noch einige 32bit libs benötigt

apt-get install lib32gcc1 lib32stdc++6 libc6-dev-i386 gcc-multilib ia32-libs

Ubuntu 9.10 bringt nur noch die libstdc++6 mit es wird aber auch Version 5 gebraucht. Einen Symlink setzen funktioniert wegen der inkompatiblem API nicht.
Unter http://packages.debian.org/stable/base/libstdc++5 kann sowohl die 32 als auch die 64bit Version eines passenden Debian Pakets bezogen werden.
Installieren dann mit

dpkg -i libstdc++5_3.3.6-18_amd64.deb

Categories: c/c++, linux Tags: , , ,

programming-wtf

October 27th, 2009 2 comments

Ich bin heut bei der Arbeit auf einen netten Codeabschnitt gestoßen, in Datei A stand:

osm_port_t *port = cl_item_obj(item, port, list_item);

So weit so gut, nur was ist dieses ‘list_item’? In der Funktion und in der Datei ist es zumindest nicht enthalten, also mal grep -R 😉

In Datei B hab ich dann diesen Spaß gefunden:

#define cl_item_obj(item_ptr, obj_ptr, item_field) (typeof(obj_ptr)) \
((void *)item_ptr - (unsigned long)&((typeof(obj_ptr))0)->item_field)

Ok, vollsten Respekt vor dem Schreiber für seinen Hack, den ich immer noch nicht verstanden hab. Ist aber auch nicht ganz so wichtig, zumal wenn ich ihn verstehen würde, würde ich ihn nicht mehr so toll finden 😉

ABER: wie zur Hölle kann man so was undokumentiert lassen!? (nix, nada, no comment)

PS: wer noch wissen will woher das stammt, aus dem SubnetManager von InfiniBand (open-source wohlgemerkt)

Categories: c/c++, hpc, linux, wtf Tags:

open64

October 16th, 2009 1 comment
Categories: c/c++, software Tags: , ,

external variables: C vs. C++

July 7th, 2009 No comments

The situation is the following: We have two source files (main and core) and want to use the same global variable (headvar) in both of them. In C thats plain easy:

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
 
int headvar; /* global var */
 
int core(int);  /* forward declaration */
 
#endif /* __HEAD_H__ */

main.c

#include <stdio .h>
#include "head.h"
 
int main()
{
        printf( "Hello World!\n" );
        printf("headvar: %d\n", headvar);
        printf("core: %d\n", core(23));
 
        return 0;
}
</stdio>

core.c

#include "head.h"
 
int core(int var)
{
    headvar=42;
    int res=0;
    res=var+headvar;
    return res;
}

In C++ this isn’t going to work as the variable is basically declared twice using the mechanisms as seen above. The reasons for that are quiet complex – you can gain more insight here: http://www.hardforum.com. I’ll only talk about the solution here. You have to make sure that there is only one single memory allocation aka instance of the variable. To ensure this you can use the keyword “external” to tell the compiler-suite that the actual definition occurs elsewhere. Using external you basically tell that there is a name refering to a variable of the given type without actual declaration. You can use this external variable in multiple locations as long as there is one single declaration in one location. So here is the sourcecode of above recoded in C++.

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
 
extern int newvar; /* external declaration */
 
int core(int);  /* forward declaration */
 
#endif /* __HEAD_H__ */

main.cpp

#include <iostream>
#include "head.h"
 
int newvar = 1;	/* actual definition */
 
int main()
{
	std::cout < < "Hello World!" << std::endl;
	std::cout << "newvar: " << newvar << std::endl;
	std::cout << "core: " << core(23) << std::endl;
 
    return 0;
}

core.cpp

#include "head.h"
 
int core(int var)
{
    int res=0;
    newvar=42; /* new value for variable defined in main.cpp */
    res=var+newvar;
    return res;
}

This is nothing new for the casual programmer but can be a real pain in the ass when the error has already been made as the error-messages are mostly “slightly” irritating.

Categories: c/c++ Tags:

compiling from sources

June 26th, 2009 No comments

I’ve been hacking around the last 4 days trying to build up a stack of 5 hpc tools all depending on each other each with a special set of features enabled – pure horror. After switching between cutting edge versions and wildly interchanging compiler-suites all with different non-positive outcome I think I’m finally done. Man vs machine 1:0 – gotcha 😉

Here 2 of the more interesting snippets I had to create to get things up an running:

# add missing string.h
echo "#include  string.h" >swap.c
cat ./SRC/SRC/mpo_LogCube3.cc >>swap.c
mv swap.c ./SRC/SRC/mpo_LogCube3.cc
# fix wrong marmotcc (missing scalasca-lib)
sed -e 's/-lcube3/-lcube3 -lsc.z/g' `which marmotcc` >marmotcc
chmod +x marmotcc
mv ./marmotcc `which marmotcc`

I had to use dos2unix as one script had windows coding and so my shell was complaining about not knowing /bin/bash^M and so on. I also wrote a script creating ./configure lines with all possible combinations of a set of flags to test which combination actually works . . .
Sometimes I’d really like those days back were a “cc hello.c -o HelloWorld” was all that was needed.

BNW

Categories: bashism, c/c++, linux, software Tags: , , ,

Displaying Enum-Names instead of Values in Errors

June 4th, 2009 1 comment

The usual lazy developer likes to print out plain error messages, which contain pure numbers and don’t mean anything. The most prominent example is Windows itself, back in the old days.

Some time ago I was once again faced with the decision how to handle errors in our plug-able class design. While trying to find a good solution I remembered an old blog post – Qt is able to create a mapping from enum integer values to their respective names. So I fiddled around a bit and came up with a pretty neat solution, which requires virtually no extra code to gain a little more meaningful error messages than plain integer values.

Here is what I came up with:

You need to sub-class an error base class, insert your error enumeration, and tell Qt that you need the value-to-name mapping for this enum. All the extras come with the base class.
If you don’t like the rest of the class, you might just want to check out BaseError::identifierToName(). That’s where the magic is happening.

A usage example:

 // --- header file ---
 class HorseError : public BaseError
 {
     Q_OBJECT
     Q_ENUMS(x)
 public:
     enum x { DOES_NOT_WANT, IS_INJURED };
 };
 
 class Horse
 {
 public:
     HorseError error;
 
     void ride();
 };
 
 // --- source file ---
 void Horse::ride()
 {
     error.activate(HorseError::DOES_NOT_WANT, "cannot happen anyways");
 }
 
 // --- using ---
 
 Horse mybeautifulhorse;
 mybeautifulhorse.ride()
 
 // operator() returns a bool
 if (mybeautifulhorse.error()) {
    // operator QString makes the error readable
    qDebug() < < mybeautifulhorse.error;
 
    exit(1);
 }

The Header File – BaseError.hpp

#ifndef BASE_ERROR_HPP
#define BASE_ERROR_HPP
 
class BaseError : private QObject                                                                                                         
{                                                                                                                                         
    Q_OBJECT
public:
 
    BaseError();
    virtual ~BaseError();
 
    /** @returns whether the error is active */
    bool active() const;                       
    /** @returns the identifier (an enum) */   
    int identifier() const;                    
    /** @returns the name of the identifier enum e.g. "MyErrorClass::MyReturnValue" */
    QString name() const;                                                             
    /** @returns the description given by activate's second parameter */              
    const QString& description() const;                                               
 
    /** throw the error */
    void activate(int identifier, const QString& description = QString());
    /** clear the state / remove the error */                             
    void deactivate();                                                    
 
 
 
    /** alias for active() */
    bool operator()() const; 
 
    /** @returns 'name() "description()"' e.g.
     * 'MyErrorClass::MyReturnValue "something meaningful"'
     */                                                    
    operator QString() const;                              
 
signals:
 
    /** emitted when the error has been activated */
    void activated();                               
 
protected:
 
    /**
     * Default implementation generates a string using the
     * "DerivedErrorClassName::EnumeratorValueName"       
     *                                                    
     * @note                                              
     * reimplement this functions to apply an own         
     * identifier-to-error-name-mapping                   
     */                                                   
    virtual QString identifierToName(int identifier) const;
 
private:
 
    bool m_active;
    int m_identifier;
    QString m_description;
};
 
 
#endif

The Source File – BaseError.cpp

#include "BaseError.hpp"
#include <qmetaenum>
 
BaseError::BaseError() : QObject(), m_active(false)
{                                                  
}                                                  
 
 
BaseError::~BaseError()
{                      
}                      
 
 
bool BaseError::operator()() const
{                                 
    return m_active;              
}                                 
 
 
BaseError::operator QString() const
{                                  
    return QString("%1 \"%2\"").arg(name()).arg(description());
}                                                              
 
 
int BaseError::identifier() const
{                                
    return m_identifier;         
}                                
 
 
QString BaseError::name() const
{
    return identifierToName(m_identifier);
}
 
 
const QString& BaseError::description() const
{
    return m_description;
}
 
 
void BaseError::activate(int identifier, const QString& description)
{
    m_identifier = identifier;
    m_description = description;
    m_active = true;
 
    emit activated();
}
 
 
void BaseError::deactivate()
{
    m_active = false;
}
 
 
QString BaseError::identifierToName(int identifier) const
{
    QStringList ret;
 
    const QMetaObject* meta = metaObject();
 
    for (int i=0; i < meta->enumeratorCount(); ++i) {
 
        QMetaEnum enumerator = meta->enumerator(i);
 
        enumerator.key(identifier);
 
        ret < < QString("%1::%2").arg(enumerator.scope()).arg(enumerator.key(identifier));
    }
 
    return ret.join(", ");
}


Categories: c/c++, qt, software Tags: , , , , ,