Вопрос выравнивания структуры C ++

Интернационализация. Деривация его является "буквой I, восемнадцатью буквами, буква N".

8
задан NJChim 21 September 2009 в 05:29
поделиться

6 ответов

Выравнивание и порядок битовых полей, как известно, зависят от реализации. Намного безопаснее объявить обычное целочисленное поле и манипулировать «битовыми полями» внутри с помощью масок и поразрядных (| & ^) операторов.

7
ответ дан 3 November 2019 в 14:38
поделиться

Я не верю, что такое поведение поддерживается в Visual Studio. В зависимости от макроса пакета я попытался использовать __ declspec (align (1)) и получил такое же поведение. Я думаю, вы застряли с 12 байтами или немного изменили порядок своей структуры.

2
ответ дан 3 November 2019 в 14:38
поделиться

Соединение устанавливается, когда вы фактически начинаете перечисление и когда вы нажимаете SubmitChanges (если необходимо внести изменения). Я не уверен, что в приведенном выше коде открыто и используется только ОДНО соединение, но я знаю, что в этих двух упомянутых мною местах вы вызовете соединение.

Вам нужно изучить LinqPad и , как его использовать , а затем димкасты . Также ознакомьтесь с их серией статей о функциях отложенного выполнения в Linq 2 Sql

. Обратите внимание, что-то вроде этого (getTenSomethingElse (s, s, s)) не запрашивает базу данных, по крайней мере, пока вы не начнете перечисление по return value

partial class MyDataContext
{
    // builds the tree to pull data from the db that matches a criteriea and pass it a ctor of another class
    public System.Linq.IQueryable<SomethingElse> getSomethingElse(string searchTerm, string searchValue, string orderBy)
    {
        var items = 
            from s in 
            this.Somethings 
            select new SomethingElse(s);

        return items.Where(searchTerm, searchValue).OrderBy(orderBy);
    }

    // calls the above method but adds take 10 to that tree
    public System.Linq.IQueryable<SomethingElse> getTenSomethingElse(string searchTerm, string searchValue, string orderBy)
    {
        var items = 
            from s in 
            this.getSomethingElse(searchTerm, searchValue, orderBy) 
            select s;

        return items.Take(10);
    }
}

IDK о вас, но я считаю, что это довольно круто, учитывая всю проделанную работу.

О, кстати, дополнительную информацию об этом расширении "Where (s, s)" можно найти на ScottGu '

0
ответ дан 3 November 2019 в 14:38
поделиться

Shorter example with only conforming code


struct unpacked {  // apparently my other example was too long and confusing
    uint32_t a;    // ...here is a much shorter example with only the conforming
    uint32_t b;    // ...code. (The other program had the gcc-specific declaration,
    uint32_t c;    // but only for test code. Still, it was a bit long.)
    uint32_t troubleMaker;
};

struct unpacked su;
char *bits = "Lorem ipsum dolor";

void f(void) {
  uint32_t x;

  memcpy(&x, bits, 4);
  su.a = x & 7;
  su.b = x >> 3 & 1;
  su.c = x >> 4 & 0x7fff;
  memcpy(&x, bits + 2, 4);
  su.troubleMaker = x >> 3 & 0xffff;
  return 0;
}
0
ответ дан 3 November 2019 в 14:38
поделиться

Сумасшедшая идея: просто сначала напишите программу, соответствующую C99 или C ++ 03


Я бы посоветовал не использовать специфичные для поставщика расширения языка C для соответствия форматам бит устройства или сети . Даже если вы заставите поля выровняться с помощью ряда языковых расширений, по одному для каждого поставщика, у вас все еще есть порядок байтов, о котором нужно беспокоиться, и у вас все еще есть структура структуры, требующая дополнительных инструкций для доступа.

Вы можете написать программа, соответствующая C99, которая будет работать на любой архитектуре или хосте с максимальной скоростью и эффективностью кеширования, используя стандартизированные функции копирования строк и памяти C API, а также функции Posix hton и ntoh.

Хорошей практикой является использование следующих функций. для которых существуют опубликованные стандарты:

C99: memcpy(), Posix: htonl(), htons(), ntohl(), ntohs()

Обновление: вот код, который должен работать одинаково везде.

0
ответ дан 3 November 2019 в 14:38
поделиться

Crazy idea: just write a C99 or C++03 -conforming program in the first place


I would suggest not using vendor-specific C language extensions to match device or network bit formats. Even if you get the fields to line up using a series of one-per-vendor language extensions, you still have byte order to worry about, and you still have a struct layout that requires extra instructions to access.

You can write a C99 conforming program that will work on any architecture or host and at maximum speed and cache efficiency by using the standardized C API string and memory copy functions and the Posix hton and ntoh functions.

A good practice is to use the following functions for which there exist published standards:

C99: memcpy(), Posix: htonl(), htons(), ntohl(), ntohs()

Update: here is some code that should work the same everywhere. You may need to get from this project if Microsoft still hasn't implemented it for C99, or just make the usual assumptions about int sizes.

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>

struct packed_with_bit_fields {  // ONLY FOR COMPARISON
    unsigned int   a        : 3;
    unsigned int   b        : 1;
    unsigned int   c        : 15;
    unsigned int   troubleMaker : 16;
    unsigned short padding  : 13;
} __attribute__((packed));       // USED ONLY TO COMPARE IMPLEMENTATIONS

struct unpacked { // THIS IS THE EXAMPLE STRUCT
    uint32_t a;
    uint32_t b;
    uint32_t c;
    uint32_t troubleMaker;
}; // NOTE NOT PACKED

struct unpacked su;
struct packed_with_bit_fields sp;
char *bits = "Lorem ipsum dolor";

int main(int ac, char **av) {
  uint32_t x;   // byte order issues ignored in both cases

  // This should work with any environment and compiler
  memcpy(&x, bits, 4);
  su.a = x & 7;
  su.b = x >> 3 & 1;
  su.c = x >> 4 & 0x7fff;
  memcpy(&x, bits + 2, 4);
  su.troubleMaker = x >> 3 & 0xffff;

  // This section works only with gcc
  memcpy(&sp, bits, 6);
  printf( sp.a == su.a
      &&  sp.b == su.b
      &&  sp.c == su.c
      &&  sp.troubleMaker == su.troubleMaker
      ? "conforming and gcc implementations match\n" : "huh?\n");
  return 0;
}
17
ответ дан 3 November 2019 в 14:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: