C++Guns – RoboBlog blogging the bot

18.02.2016

Nahkauf + Linux

Filed under: Allgemein — Tags: — Thomas @ 18:02

Der tolle Supermarkt nahkauf betreibt auf seinen Kassenrechnern Linux :D Ein Phoenix BIOS mit LILO Bootloader. Heute zufällig gesehen, als sie die Kiste neu gestartet hatten.
LILO.. das Zeug muss uralt sein. Oder hat jemand in den letzten 10 Jahren LILO installiert? :D :D :D

17.02.2016

Fortran: Detect 64bit 32bit

Filed under: Allgemein — Tags: — Thomas @ 08:02

Ein möglicher Weg zu erkennen ob auf einer 64bit oder 32bit Maschine compiliert wird ist mit Hilfe
von macros. Die üblichen macros wie __amd64, __amd64__, __x86_64 __x86_64__ funktionieren unter gfortran (nicht) mehr, da sie nur zeigen ob eine 64Bit Prozessor zur Verfügung steht. Und nicht, ob man
auch wirklich für 64bit compiliert. [1]
Es ist natürlich möglich untr 64bit OS für 32bit zu compilieren, wenn zum Beispiel nur ein 32bit Compiler zur Verfügung steht. Oder zu Testzwecken

Laut doku [2] steht zu diesem Zwecke das macro __LP64__ zur Verfügung.

__LP64__
_LP64
These macros are defined, with value 1, if (and only if) the compilation is for a target where long int and pointer both use 64-bits and int uses 32-bit.

Pointer ist 64bit und integer ist 32bit. So ist es richtig. Alle anderen (M$) machen es falsch.

Nun gibt es leider Compiler, die kein Preprocessing beherrschen. Zum Glück gibt es Fortran 2003
mit dem neuen iso_c_binding Modul. Das Symbol C_INTPTR_T repräsentiert die Größe eines
Pointers und kann als KIND parameter benutzt werden.


program main
  use, intrinsic :: iso_c_binding
  implicit none
  integer(kind=C_INTPTR_T) :: sizeofapointer
  
!__LP64__
!_LP64
! These macros are defined, with value 1, if (and only if) the compilation is for a target where long int and pointer both use 64-bits and int uses 32-bit. 
#ifdef __LP64__
  write(*,*) "64bit detected by macro"
#else
  write(*,*) "32bit detected by macro"
#endif

  write(*,*) "C_INTPTR_T",  C_INTPTR_T
end program

PS: Es ist möglich mit gfortran für 32bit zu compilieren. Einfach gfortran-multilib installieren
und dem Compiler -m32 geben.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47175
[2] https://gcc.gnu.org/onlinedocs/gcc-4.2.1/cpp/Common-Predefined-Macros.html

12.02.2016

/proc status

Filed under: Allgemein — Tags: — Thomas @ 20:02

Code snipped to read /proc status with fortran.
E.g. used memory and so...


! original: http://hiliev.eu/posts/recipe-obtaining-peak-vm-memory-size-in-pure-fortran.html

module ProcStatus
  contains
    !---------------------------------------------------------------!
    ! Returns current process virtual memory size             !
    ! Requires Linux procfs mounted at /proc                        !
    !---------------------------------------------------------------!
    ! Output: vmsize - vmsize VM size in kB                             !
    !---------------------------------------------------------------!
    function getVmSize() result(vmsize)
      implicit none
      integer :: vmsize
      character(len=80) :: stat_key, stat_value
      !
      vmsize = 0
      open(unit=1000, file="/proc/self/status", status='old', err=99)
      do while (.true.)
        read(unit=1000, fmt=*, err=88) stat_key, stat_value
        if (stat_key == 'VmSize:') then
          read(stat_value, *) vmsize
          exit
        end if
      end do
    88 close(unit=1000)
      if (vmsize == 0) goto 99
      return
      !
    99 print *, 'ERROR: procfs not mounted or not compatible'
      vmsize = -1
    end function getVmSize

end module ProcStatus

program test
  use ProcStatus
  implicit none
  integer :: vmsize
  integer, allocatable :: arr(:)

  allocate(arr(10000000)) ! ~ 40MB
  arr(:) = 0

  vmsize = getVmSize()
  print *, 'VM size: ', vmsize, ' kB'
end program test

02.02.2016

C gecaste (Bug of the day 10)

Filed under: Allgemein — Tags: — Thomas @ 10:02

Ist nicht direkt ein Bug, aber kann ganz leicht zu einem werden. Vorallem stört das rum-gecaste und Pointer auf locale Variablen. Hier ein Stück Code, wo ich erst drei mal hinschauen musste


typedef struct s_rocsmq_message {
...
} t_rocsmq_message, *p_rocsmq_message;

void func() {
  t_rocsmq_message message;
  rocsmq_recv(..., (p_rocsmq_message) & message, ROCSMQ_POLL)
}

Aber, ich sollte weniger mich beschweren, ehr Hilfe leisten.
Hier eine sehr einfache C++ version ohne Extras:


namespace rocs{
struct mqMessage {
...
};
}

using namespace rocs;
void func() {
  mqMessage message = mqRecv(...);
}

Keine Pointer, kein gecaste. Lokale Variable dann declariert und gleich initialisiert, wenn man sie braucht.
Projektname "rocs" aus den Datentypen und Funktionsnamen entfernt und in ein namespace ausgelagert. Verständlicher,
weniger Code, weniger Fehler.

Powered by WordPress