2017-01-24 1 views
0

Я планирую преобразовать некоторые программы, написанные на C/C++, в Ada. Они делают интенсивное использование постоянных литералов гольцов часто, как рваные массивы, такие как:Как использовать refs для постоянных строк в массивах и записях?

const char * stringsA = { "Up", "Down", "Shutdown" }; 

или строковых ссылки в записях, как:

typedef struct 
    { 
    int something; 
    const char * regexp; 
    const char * errormsg 
    } ERRORDESCR; 
ERRORDESCR edscrs [ ] = 
    { 
    { 1, "regexpression1", "Invalid char in person name" }, 
    { 2, "regexp2", "bad bad" } 
    }; 

пресеты рассчитываются/C++ компилятор C и я хочу Компилятор Ada должен быть в состоянии сделать это тоже.

Я использовал Google и искал рваные массивы, но мог найти только два способа: предустановка строк. Один в обосновании для Ada 95 Джона Барнса и еще по адресу http://computer-programming-forum.com/44-ada/d4767ad6125feac7.htm. Они показаны как строки A и строки B ниже. StringsA определяется в два этапа, что немного утомительно, если для настройки нужно создать сотни строк. StringsB использует только один шаг, но зависит от компилятора.

Вопрос 1: Существуют ли другие способы? Вопрос 2: будут ли второй строки работать с GNAT Ada?

Я не начал конвертировать. Пакеты ниже только для экспериментов и обучая себя ...

package ragged is 
    type String_ptr is access constant String; 
    procedure mydummy; 
end ragged; 

package body ragged is 
    s1: aliased constant String := "Up"; 
    s2: aliased constant String := "Down"; 
    s3: aliased constant String := "Shutdown"; 

    stringsA: array (1 .. 3) of String_ptr := 
    (s1'Access, s2'Access, s3'Access); -- works 

    stringsB: array (1 .. 3) of String_ptr := 
     (new String'("Up"), new String'("Down"), 
     new String'("Shutdown")); -- may work, compiler-dependent 

    -- this would be convenient and clear... 
    --stringsC: array (1 .. 3) of String_ptr := 
    -- ("Up", "Down", "Shutdown"); -- BUT Error, expected String_ptr values 

    --stringsD: array (1 .. 3) of String_ptr := 
    --("Up"'Access, "Down"'Access, "Shutdown"'Access); --Error - bad Access use 

    --stringsE: array (1 .. 3) of String_ptr := 
    --(String_ptr("Up"), String_ptr("Down"), 
    -- String_ptr("Shutdown")); -- Error, invalid conversion 

    procedure mydummy is 
    begin 
    null; 
    end; 
end ragged; 
+2

выглядит как дубликат http://stackoverflow.com/questions/41151494/ada-constant-array-of-string-literals –

+0

я гугл, но пропустил подобные сообщения. Я сделал тестовую программу и обнаружил, что stringsA и stringsB работают для GNAT Ada. Однако оба подхода являются подробными и загроможденными по сравнению с версией C const char * strings [] = {«Вверх», «Вниз», «Выключение»}; Ada новички с C, Java, JS и C# и т. Д. Современный языковой фон, скорее всего, будет разочарован. – resander

+0

Почему ваш B пример должен быть зависимым от компилятора? Это уродливо, да, но я не вижу зависимости компилятора. –

ответ

1

Немного рассудительный оператор перегрузка может сделать это менее суматоху образом:

(в пределах тело пакета)

function New_String(S : String) return String_Ptr is 
    begin 
     return new String'(S); 
    end New_String; 

    function "+" (S : String) return String_Ptr renames New_String; 

Теперь вы можете сделать:

stringsC: array (1 .. 3) of String_ptr := (+"Up", +"Down", +"Shutdown"); 
+0

Это действительно хорошо! По сути, такие же, как C-подобные языки.Попробуем и отчитаемся. – resander

+0

Я написал небольшую тестовую программу для строкC. Значения вышли правильно, но были созданы во время выполнения не во время компиляции. Я устанавливал точки останова при возврате нового String '(S) и в объявлении массива stringsC, и оба были вызваны. Я также использовал Debug/Data/Display в начале основной программы для просмотра stringsC (1) ... и все получилось NULL. Когда я отображал stringsA и stringsB в начале, они вышли правильно. Я раньше не использовал Аду, поэтому я могу ошибаться. Тестпрограмма находится в следующем окне ответа. – resander

+0

У GNAT есть схема, чтобы распознать, что 'new String '(« Up »)' можно оптимизировать, как хотелось бы, но не '+" Up ". Интересно, что использование '-gnatG' показывает, что' StringsB' представлен внутри, как 'StringsA'! –

0

Не хватает места в ком Мента для этого программы испытаний

package raggedtest is 
    type String_ptr is access constant String; 
    procedure mytest; 
end raggedtest; 

with ada.text_IO; use Ada.Text_IO; 
package body raggedtest is 
    s1: aliased constant String := "Up"; 
    s2: aliased constant String := "Down"; 
    s3: aliased constant String := "Shutdown"; 
    stringsA: array (1 .. 3) of String_ptr := 
    (s1'Access, s2'Access, s3'Access); 

    stringsB: array (1 .. 3) of String_ptr := 
     (new String'("UpB"), new String'("DownB"), 
     new String'("ShutdownB")); 

    function New_String(S : String) return String_Ptr is 
    begin 
     return new String'(S); 
    end New_String; 
    function "+" (S : String) return String_Ptr renames New_String; 
    stringsC: array (1 .. 3) of String_ptr := (+"UpC", +"DownC", +"ShutdownC"); 


    procedure mytest is 
    begin 
     put ("s1A: "); put(stringsA(1).all); New_line; 
     put ("s2A "); put(stringsA(2).all); New_line; 
     put ("s3A: "); put(stringsA(3).all); New_line; 

     put ("s1B: "); put(stringsB(1).all); New_line; 
     put ("s2B "); put(stringsB(2).all); New_line; 
     put ("s3B: "); put(stringsB(3).all); New_line; 

     put ("s1C: "); put(stringsC(1).all); New_line; 
     put ("s2C "); put(stringsC(2).all); New_line; 
    put ("s3C: "); put(stringsC(3).all); New_line; 
    end; 
end raggedtest; 

with raggedtest; use raggedtest; 
procedure main is 
begin 
    mytest; 
end main; 
Смежные вопросы