From: Robert Feldt Date: 2003-09-11T20:25:15+09:00 Subject: Re: Nested struct alignment summarized Mauricio Fern�ndez skrev den Thu, 11 Sep 2003 17:35:15 +0900: > On Thu, Sep 11, 2003 at 04:07:14PM +0900, Robert Feldt wrote: >> So the situation look grim; even if we find a portable >> way to check how a certain compiler lays things out >> it may not lay things out in the same way for different >> structs. There could be special situation where it changes the layout. >> >> So is there anything we can do? > > Expand the current method (list of structure types in dl.h (ALIGN_*)), > so that the alignments for a growing number of structs are determined > at compile time? > > Of course, that'd require some code to check for structural equivalence > of emm structures. > Below is code to assist analysis of this. I'd be interested in the output from the script on other machines and with other compilers. I've run it on a PC/WinXP/Cygwin Ruby version: 1.8.0 (2003-09-08) [i386-cygwin] Compiler: gcc Version: gcc (GCC) 3.2 20020927 (prerelease) and a Gentoo Linux machine Ruby version: 1.8.0 (2003-08-04) [i686-linux-gnu] Compiler: gcc Version: gcc (GCC) 3.2.3 20030422 (Gentoo Linux 1.4 3.2.3-r1, propo lice) and results differ in how they align double's. They both inline structs directly into the outer struct though. Regards, Robert require 'dl/import' require 'dl/struct' your_name, your_mail = ARGV[0], ARGV[1] compiler = ARGV[2] || "gcc" compile_cmd = ARGV[3] || "-shared -o DLLNAME" version_cmd = ARGV[4] || "--version" class CFile def initialize(compiler, compileCommand, versionCommand) @co, @cc, @vc = compiler, compileCommand, versionCommand @count = 0 end def compile_to_dll(dllname = "test.so", code = "", cfilename = "test.c") File.open(cfilename, "w") {|fh| fh.write code} cmd = "#{@co} #{@cc} #{cfilename}".gsub("DLLNAME", dllname) system cmd File.delete cfilename end def compiler_version `#{@co} #{@vc}` end Template = < tfrst, t2 => tsnd} adiffs = cf.address_diffs(th) results << ["#{t1} #{tfrst}, #{t2} #{tsnd}:", adiffs] counts[adiffs] += 1 STDERR.print "."; STDERR.flush end end most_common = counts.to_a.sort {|a,b| b.last <=> a.last}.first.first puts "The address diffs are #{most_common.inspect} for all combinations but:" # Print the uncommon ones results.each {|r| puts "#{r[0]} #{r[1].inspect}" unless r[1] == most_common}