Why is a Java array index expression evaluated before checking if the array reference expression is null?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








38















According to the JLS, runtime evaluation of an array access expression behaves as follows:



  1. First, the array reference expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason and the index expression is not
    evaluated.

  2. Otherwise, the index expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason.

  3. Otherwise, if the value of the array
    reference expression is null, then a NullPointerException is thrown.

So this code will print: java.lang.NullPointerException, index=2



class Test3 
public static void main(String args)
int index = 1;
try
nada()[index = 2]++;
catch (Exception e)
System.out.println(e + ", index=" + index);



static int nada()
return null;




The question is: for what reason do we need to first evaluate the index = 2 expression and not just throw the NullPointerException once the array reference is evaluated to null? Or in other words - why is the order 1,2,3 and not 1,3,2?










share|improve this question



















  • 1





    Firstly you have to initialize an array and secondly the priority of equals sign is high that's why its given null pointer exception.

    – Ammar Ali
    Mar 14 at 11:10






  • 8





    Asking on SO why the JLS is written the way it is will not give you any good answer unless it maybe comes from one of the designers of the Java language.

    – Seelenvirtuose
    Mar 14 at 11:17







  • 4





    They had to choose something, and both options can produce "unexpected" scenarios. (I.e. scenarios that behave in a not very intuitive way). The option that was chosen seems to be more in line with how expression evaluation works in other parts of Java.

    – biziclop
    Mar 14 at 11:35






  • 2





    … which in turn is a duplicate of Is the array index or the assigned value evaluated first?

    – fantaghirocco
    Mar 14 at 13:22












  • @fantaghirocco i didn't ask about how java evaluates an array index expression, it's described in the question. I just wanted to know what the reason behind that's behavior.

    – Andrei Nepsha
    Mar 14 at 13:43


















38















According to the JLS, runtime evaluation of an array access expression behaves as follows:



  1. First, the array reference expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason and the index expression is not
    evaluated.

  2. Otherwise, the index expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason.

  3. Otherwise, if the value of the array
    reference expression is null, then a NullPointerException is thrown.

So this code will print: java.lang.NullPointerException, index=2



class Test3 
public static void main(String args)
int index = 1;
try
nada()[index = 2]++;
catch (Exception e)
System.out.println(e + ", index=" + index);



static int nada()
return null;




The question is: for what reason do we need to first evaluate the index = 2 expression and not just throw the NullPointerException once the array reference is evaluated to null? Or in other words - why is the order 1,2,3 and not 1,3,2?










share|improve this question



















  • 1





    Firstly you have to initialize an array and secondly the priority of equals sign is high that's why its given null pointer exception.

    – Ammar Ali
    Mar 14 at 11:10






  • 8





    Asking on SO why the JLS is written the way it is will not give you any good answer unless it maybe comes from one of the designers of the Java language.

    – Seelenvirtuose
    Mar 14 at 11:17







  • 4





    They had to choose something, and both options can produce "unexpected" scenarios. (I.e. scenarios that behave in a not very intuitive way). The option that was chosen seems to be more in line with how expression evaluation works in other parts of Java.

    – biziclop
    Mar 14 at 11:35






  • 2





    … which in turn is a duplicate of Is the array index or the assigned value evaluated first?

    – fantaghirocco
    Mar 14 at 13:22












  • @fantaghirocco i didn't ask about how java evaluates an array index expression, it's described in the question. I just wanted to know what the reason behind that's behavior.

    – Andrei Nepsha
    Mar 14 at 13:43














38












38








38


4






According to the JLS, runtime evaluation of an array access expression behaves as follows:



  1. First, the array reference expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason and the index expression is not
    evaluated.

  2. Otherwise, the index expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason.

  3. Otherwise, if the value of the array
    reference expression is null, then a NullPointerException is thrown.

So this code will print: java.lang.NullPointerException, index=2



class Test3 
public static void main(String args)
int index = 1;
try
nada()[index = 2]++;
catch (Exception e)
System.out.println(e + ", index=" + index);



static int nada()
return null;




The question is: for what reason do we need to first evaluate the index = 2 expression and not just throw the NullPointerException once the array reference is evaluated to null? Or in other words - why is the order 1,2,3 and not 1,3,2?










share|improve this question
















According to the JLS, runtime evaluation of an array access expression behaves as follows:



  1. First, the array reference expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason and the index expression is not
    evaluated.

  2. Otherwise, the index expression is evaluated. If this
    evaluation completes abruptly, then the array access completes
    abruptly for the same reason.

  3. Otherwise, if the value of the array
    reference expression is null, then a NullPointerException is thrown.

So this code will print: java.lang.NullPointerException, index=2



class Test3 
public static void main(String args)
int index = 1;
try
nada()[index = 2]++;
catch (Exception e)
System.out.println(e + ", index=" + index);



static int nada()
return null;




The question is: for what reason do we need to first evaluate the index = 2 expression and not just throw the NullPointerException once the array reference is evaluated to null? Or in other words - why is the order 1,2,3 and not 1,3,2?







java language-lawyer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 14 at 16:09









senseiwu

2,23411333




2,23411333










asked Mar 14 at 11:00









Andrei NepshaAndrei Nepsha

19619




19619







  • 1





    Firstly you have to initialize an array and secondly the priority of equals sign is high that's why its given null pointer exception.

    – Ammar Ali
    Mar 14 at 11:10






  • 8





    Asking on SO why the JLS is written the way it is will not give you any good answer unless it maybe comes from one of the designers of the Java language.

    – Seelenvirtuose
    Mar 14 at 11:17







  • 4





    They had to choose something, and both options can produce "unexpected" scenarios. (I.e. scenarios that behave in a not very intuitive way). The option that was chosen seems to be more in line with how expression evaluation works in other parts of Java.

    – biziclop
    Mar 14 at 11:35






  • 2





    … which in turn is a duplicate of Is the array index or the assigned value evaluated first?

    – fantaghirocco
    Mar 14 at 13:22












  • @fantaghirocco i didn't ask about how java evaluates an array index expression, it's described in the question. I just wanted to know what the reason behind that's behavior.

    – Andrei Nepsha
    Mar 14 at 13:43













  • 1





    Firstly you have to initialize an array and secondly the priority of equals sign is high that's why its given null pointer exception.

    – Ammar Ali
    Mar 14 at 11:10






  • 8





    Asking on SO why the JLS is written the way it is will not give you any good answer unless it maybe comes from one of the designers of the Java language.

    – Seelenvirtuose
    Mar 14 at 11:17







  • 4





    They had to choose something, and both options can produce "unexpected" scenarios. (I.e. scenarios that behave in a not very intuitive way). The option that was chosen seems to be more in line with how expression evaluation works in other parts of Java.

    – biziclop
    Mar 14 at 11:35






  • 2





    … which in turn is a duplicate of Is the array index or the assigned value evaluated first?

    – fantaghirocco
    Mar 14 at 13:22












  • @fantaghirocco i didn't ask about how java evaluates an array index expression, it's described in the question. I just wanted to know what the reason behind that's behavior.

    – Andrei Nepsha
    Mar 14 at 13:43








1




1





Firstly you have to initialize an array and secondly the priority of equals sign is high that's why its given null pointer exception.

– Ammar Ali
Mar 14 at 11:10





Firstly you have to initialize an array and secondly the priority of equals sign is high that's why its given null pointer exception.

– Ammar Ali
Mar 14 at 11:10




8




8





Asking on SO why the JLS is written the way it is will not give you any good answer unless it maybe comes from one of the designers of the Java language.

– Seelenvirtuose
Mar 14 at 11:17






Asking on SO why the JLS is written the way it is will not give you any good answer unless it maybe comes from one of the designers of the Java language.

– Seelenvirtuose
Mar 14 at 11:17





4




4





They had to choose something, and both options can produce "unexpected" scenarios. (I.e. scenarios that behave in a not very intuitive way). The option that was chosen seems to be more in line with how expression evaluation works in other parts of Java.

– biziclop
Mar 14 at 11:35





They had to choose something, and both options can produce "unexpected" scenarios. (I.e. scenarios that behave in a not very intuitive way). The option that was chosen seems to be more in line with how expression evaluation works in other parts of Java.

– biziclop
Mar 14 at 11:35




2




2





… which in turn is a duplicate of Is the array index or the assigned value evaluated first?

– fantaghirocco
Mar 14 at 13:22






… which in turn is a duplicate of Is the array index or the assigned value evaluated first?

– fantaghirocco
Mar 14 at 13:22














@fantaghirocco i didn't ask about how java evaluates an array index expression, it's described in the question. I just wanted to know what the reason behind that's behavior.

– Andrei Nepsha
Mar 14 at 13:43






@fantaghirocco i didn't ask about how java evaluates an array index expression, it's described in the question. I just wanted to know what the reason behind that's behavior.

– Andrei Nepsha
Mar 14 at 13:43













4 Answers
4






active

oldest

votes


















37














An array access expression has two sub-expressions:




An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).




The two sub-expressions are evaluated before the array access expression itself, in order to evaluate the expression.



After evaluating the two sub-expressions



nada()[index = 2]++;


becomes



null[2]++;


Only now the expression is evaluated and the NullPointerException is thrown.



This is consistent with the evaluation of most expressions in Java (the only counter examples I can think of are short circuiting operators such as && and ||).



For example, if you make the following method call:



firstMethod().secondMethod(i = 2);


First you evaluate firstMethod() and i = 2, and only later you throw NullPointerException if firstMethod() evaluated to null.






share|improve this answer






























    14














    This is because in the generated bytecode there are no explicit null checks.



    nada()[index = 2]++;


    is translated into the following byte code:



    // evaluate the array reference expression
    INVOKESTATIC Test3.nada ()[I
    // evaluate the index expression
    ICONST_2
    DUP
    ISTORE 1
    // access the array
    // if the array reference expression was null, the IALOAD operation will throw a null pointer exception
    DUP2
    IALOAD
    ICONST_1
    IADD
    IASTORE





    share|improve this answer























    • That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

      – Holger
      Apr 4 at 16:16


















    8














    The basic byte code operations are (for an int)



    ALOAD array_address
    ILOAD index
    IALOAD array_element_retrieval


    The IALOAD does the null pointer check. In reality the code is a bit more elaborate:



    1. calculate array address

    2. calculate index

    3. IALOAD

    So the answer is: it would need an extra checking operation after the array address is loaded, in anticipation of the array access.



    Behavior by straight implementation.






    share|improve this answer






























      8














      The decision may be partially be rooted in performance.



      In order to know that index = 2 is not going to be required, we would have to first evaluate nada() and then check whether it was null. We would then branch on the result of this condition, and decide whether or not to evaluate the array index expression.



      Every perfectly valid array index expression would be made slower by one additional operation, just for the sake of saving code - code that is going to throw an exception anyway - from evaluating one expression unnecessarily.



      It is an optimistic approach which works better in the majority of cases.






      share|improve this answer























        Your Answer






        StackExchange.ifUsing("editor", function ()
        StackExchange.using("externalEditor", function ()
        StackExchange.using("snippets", function ()
        StackExchange.snippets.init();
        );
        );
        , "code-snippets");

        StackExchange.ready(function()
        var channelOptions =
        tags: "".split(" "),
        id: "1"
        ;
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function()
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled)
        StackExchange.using("snippets", function()
        createEditor();
        );

        else
        createEditor();

        );

        function createEditor()
        StackExchange.prepareEditor(
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader:
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        ,
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        );



        );













        draft saved

        draft discarded


















        StackExchange.ready(
        function ()
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55160799%2fwhy-is-a-java-array-index-expression-evaluated-before-checking-if-the-array-refe%23new-answer', 'question_page');

        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        37














        An array access expression has two sub-expressions:




        An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).




        The two sub-expressions are evaluated before the array access expression itself, in order to evaluate the expression.



        After evaluating the two sub-expressions



        nada()[index = 2]++;


        becomes



        null[2]++;


        Only now the expression is evaluated and the NullPointerException is thrown.



        This is consistent with the evaluation of most expressions in Java (the only counter examples I can think of are short circuiting operators such as && and ||).



        For example, if you make the following method call:



        firstMethod().secondMethod(i = 2);


        First you evaluate firstMethod() and i = 2, and only later you throw NullPointerException if firstMethod() evaluated to null.






        share|improve this answer



























          37














          An array access expression has two sub-expressions:




          An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).




          The two sub-expressions are evaluated before the array access expression itself, in order to evaluate the expression.



          After evaluating the two sub-expressions



          nada()[index = 2]++;


          becomes



          null[2]++;


          Only now the expression is evaluated and the NullPointerException is thrown.



          This is consistent with the evaluation of most expressions in Java (the only counter examples I can think of are short circuiting operators such as && and ||).



          For example, if you make the following method call:



          firstMethod().secondMethod(i = 2);


          First you evaluate firstMethod() and i = 2, and only later you throw NullPointerException if firstMethod() evaluated to null.






          share|improve this answer

























            37












            37








            37







            An array access expression has two sub-expressions:




            An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).




            The two sub-expressions are evaluated before the array access expression itself, in order to evaluate the expression.



            After evaluating the two sub-expressions



            nada()[index = 2]++;


            becomes



            null[2]++;


            Only now the expression is evaluated and the NullPointerException is thrown.



            This is consistent with the evaluation of most expressions in Java (the only counter examples I can think of are short circuiting operators such as && and ||).



            For example, if you make the following method call:



            firstMethod().secondMethod(i = 2);


            First you evaluate firstMethod() and i = 2, and only later you throw NullPointerException if firstMethod() evaluated to null.






            share|improve this answer













            An array access expression has two sub-expressions:




            An array access expression contains two subexpressions, the array reference expression (before the left bracket) and the index expression (within the brackets).




            The two sub-expressions are evaluated before the array access expression itself, in order to evaluate the expression.



            After evaluating the two sub-expressions



            nada()[index = 2]++;


            becomes



            null[2]++;


            Only now the expression is evaluated and the NullPointerException is thrown.



            This is consistent with the evaluation of most expressions in Java (the only counter examples I can think of are short circuiting operators such as && and ||).



            For example, if you make the following method call:



            firstMethod().secondMethod(i = 2);


            First you evaluate firstMethod() and i = 2, and only later you throw NullPointerException if firstMethod() evaluated to null.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 14 at 11:30









            EranEran

            292k37482564




            292k37482564























                14














                This is because in the generated bytecode there are no explicit null checks.



                nada()[index = 2]++;


                is translated into the following byte code:



                // evaluate the array reference expression
                INVOKESTATIC Test3.nada ()[I
                // evaluate the index expression
                ICONST_2
                DUP
                ISTORE 1
                // access the array
                // if the array reference expression was null, the IALOAD operation will throw a null pointer exception
                DUP2
                IALOAD
                ICONST_1
                IADD
                IASTORE





                share|improve this answer























                • That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

                  – Holger
                  Apr 4 at 16:16















                14














                This is because in the generated bytecode there are no explicit null checks.



                nada()[index = 2]++;


                is translated into the following byte code:



                // evaluate the array reference expression
                INVOKESTATIC Test3.nada ()[I
                // evaluate the index expression
                ICONST_2
                DUP
                ISTORE 1
                // access the array
                // if the array reference expression was null, the IALOAD operation will throw a null pointer exception
                DUP2
                IALOAD
                ICONST_1
                IADD
                IASTORE





                share|improve this answer























                • That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

                  – Holger
                  Apr 4 at 16:16













                14












                14








                14







                This is because in the generated bytecode there are no explicit null checks.



                nada()[index = 2]++;


                is translated into the following byte code:



                // evaluate the array reference expression
                INVOKESTATIC Test3.nada ()[I
                // evaluate the index expression
                ICONST_2
                DUP
                ISTORE 1
                // access the array
                // if the array reference expression was null, the IALOAD operation will throw a null pointer exception
                DUP2
                IALOAD
                ICONST_1
                IADD
                IASTORE





                share|improve this answer













                This is because in the generated bytecode there are no explicit null checks.



                nada()[index = 2]++;


                is translated into the following byte code:



                // evaluate the array reference expression
                INVOKESTATIC Test3.nada ()[I
                // evaluate the index expression
                ICONST_2
                DUP
                ISTORE 1
                // access the array
                // if the array reference expression was null, the IALOAD operation will throw a null pointer exception
                DUP2
                IALOAD
                ICONST_1
                IADD
                IASTORE






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Mar 14 at 11:27









                Thomas KlägerThomas Kläger

                7,1512819




                7,1512819












                • That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

                  – Holger
                  Apr 4 at 16:16

















                • That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

                  – Holger
                  Apr 4 at 16:16
















                That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

                – Holger
                Apr 4 at 16:16





                That’s swapping cause and effect. If the specification said the null-tests had to happen before the index evaluation, there were explicit null checks.

                – Holger
                Apr 4 at 16:16











                8














                The basic byte code operations are (for an int)



                ALOAD array_address
                ILOAD index
                IALOAD array_element_retrieval


                The IALOAD does the null pointer check. In reality the code is a bit more elaborate:



                1. calculate array address

                2. calculate index

                3. IALOAD

                So the answer is: it would need an extra checking operation after the array address is loaded, in anticipation of the array access.



                Behavior by straight implementation.






                share|improve this answer



























                  8














                  The basic byte code operations are (for an int)



                  ALOAD array_address
                  ILOAD index
                  IALOAD array_element_retrieval


                  The IALOAD does the null pointer check. In reality the code is a bit more elaborate:



                  1. calculate array address

                  2. calculate index

                  3. IALOAD

                  So the answer is: it would need an extra checking operation after the array address is loaded, in anticipation of the array access.



                  Behavior by straight implementation.






                  share|improve this answer

























                    8












                    8








                    8







                    The basic byte code operations are (for an int)



                    ALOAD array_address
                    ILOAD index
                    IALOAD array_element_retrieval


                    The IALOAD does the null pointer check. In reality the code is a bit more elaborate:



                    1. calculate array address

                    2. calculate index

                    3. IALOAD

                    So the answer is: it would need an extra checking operation after the array address is loaded, in anticipation of the array access.



                    Behavior by straight implementation.






                    share|improve this answer













                    The basic byte code operations are (for an int)



                    ALOAD array_address
                    ILOAD index
                    IALOAD array_element_retrieval


                    The IALOAD does the null pointer check. In reality the code is a bit more elaborate:



                    1. calculate array address

                    2. calculate index

                    3. IALOAD

                    So the answer is: it would need an extra checking operation after the array address is loaded, in anticipation of the array access.



                    Behavior by straight implementation.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Mar 14 at 11:35









                    Joop EggenJoop Eggen

                    79k755105




                    79k755105





















                        8














                        The decision may be partially be rooted in performance.



                        In order to know that index = 2 is not going to be required, we would have to first evaluate nada() and then check whether it was null. We would then branch on the result of this condition, and decide whether or not to evaluate the array index expression.



                        Every perfectly valid array index expression would be made slower by one additional operation, just for the sake of saving code - code that is going to throw an exception anyway - from evaluating one expression unnecessarily.



                        It is an optimistic approach which works better in the majority of cases.






                        share|improve this answer



























                          8














                          The decision may be partially be rooted in performance.



                          In order to know that index = 2 is not going to be required, we would have to first evaluate nada() and then check whether it was null. We would then branch on the result of this condition, and decide whether or not to evaluate the array index expression.



                          Every perfectly valid array index expression would be made slower by one additional operation, just for the sake of saving code - code that is going to throw an exception anyway - from evaluating one expression unnecessarily.



                          It is an optimistic approach which works better in the majority of cases.






                          share|improve this answer

























                            8












                            8








                            8







                            The decision may be partially be rooted in performance.



                            In order to know that index = 2 is not going to be required, we would have to first evaluate nada() and then check whether it was null. We would then branch on the result of this condition, and decide whether or not to evaluate the array index expression.



                            Every perfectly valid array index expression would be made slower by one additional operation, just for the sake of saving code - code that is going to throw an exception anyway - from evaluating one expression unnecessarily.



                            It is an optimistic approach which works better in the majority of cases.






                            share|improve this answer













                            The decision may be partially be rooted in performance.



                            In order to know that index = 2 is not going to be required, we would have to first evaluate nada() and then check whether it was null. We would then branch on the result of this condition, and decide whether or not to evaluate the array index expression.



                            Every perfectly valid array index expression would be made slower by one additional operation, just for the sake of saving code - code that is going to throw an exception anyway - from evaluating one expression unnecessarily.



                            It is an optimistic approach which works better in the majority of cases.







                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Mar 14 at 11:48









                            MichaelMichael

                            21.9k83673




                            21.9k83673



























                                draft saved

                                draft discarded
















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid


                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.

                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function ()
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55160799%2fwhy-is-a-java-array-index-expression-evaluated-before-checking-if-the-array-refe%23new-answer', 'question_page');

                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown






                                Popular posts from this blog

                                How to check contact read email or not when send email to Individual?

                                Bahrain

                                Postfix configuration issue with fips on centos 7; mailgun relay